タイトルに似ています。 新しいプログラマとして、私のプロジェクトの仕組みを知ることは非常に重要で、それを使うことの違いは何ですか?どの男が私に答えを与えることができます、ありがとう!抽象基本クラスのコールバック関数と仮想関数の使用の違いは何ですか?
答えて
仮想関数はコールバックを提供する1つのメカニズムですが、それだけではありません。
コールバックの一般性は、パラメータ、メソッド、メソッドを呼び出すオブジェクト、渡す関数によって呼び出されるオブジェクト、またはその関数によって格納されるオブジェクトを渡すことですイベントが発生したときに後で呼び出されます。
このようなメカニズムを実装する1つの方法は、基本クラスから派生し、仮想関数を実装するオブジェクトへのポインタまたは参照を渡すことです。
もう1つの方法は、関数ポインタを渡すことです。
さらに、機能ポインタを持つオブジェクトを渡すことができます。これは、どのような追加機能があるかです。機能を高めるコンストラクタ(多くの場合、boost::bind
)は巧みにそのようなオブジェクトを作成します。
C++ 11では、コールバックとして渡すために無名関数をオンザフライで構築することができます。これは通常ラムダと呼ばれます。
仮想関数をコールバックとして使用するメカニズムについてもう少し詳しく説明します。これは、行うには、かなりきちんとしたもののように見えることができます。
class Handler
{
public:
virtual ~Handler() {}
virtual void process(std::string const& message) = 0;
};
void getMessage(Handler& handler)
{
std::string str = getAMessage();
handler.process(str);
}
でも整然とハンドラをこのように構成することである。
class Handler
{
public:
virtual ~Handler() {}
void process(std::string const& message)
{
// can log or put in a breakpoint here on debugging
doProcess(message);
}
protected: // or private
virtual void doProcess(std::string const& message) = 0;
};
ここでの利点は、にデバッグすることは容易であるということです。
Handlerオブジェクトのライフタイムを管理する必要がある場合、つまりコールバックが非同期に発生する場合は、より複雑になります。次に、両側が参照を保持するようにshared_ptr<Handler>
を使用する必要があり、それが管理されます。
これを行うことで、通常のコールバック関数よりも大きな利点は、オブジェクトに余分な情報を保持できることです。コールバック自体は固定数のパラメータしか取ることができません。コールバックでは、しばしばvoid *を使用して余分な情報を取得するために何かにキャストする必要があります。このクラスを使用すると、メンバ変数にその情報を保持することができます。また、メソッドが呼び出された後にクラスが状態を保持できるようになります。
しかし、このような抽象クラスを作成してそこからクラスを派生させなければならないということです。
これは、ブースト機能とバインドが非常に便利になる場所です。本当に必要なのは、呼び出される特定のシグネチャを持つ関数で、このコールバックを処理するために余分なクラスを作成する必要はありません。したがって、この状況をはるかに迅速にプログラムすることができます。
しかし、残念ながら欠点もあります。ブースト機能は、デバッグがはるかに難しいです。あなたはブースト機能自体の寿命を管理することに注意する必要はありませんが、あなたはそれに渡すパラメータに注意する必要があります。それはあなたがそれらを渡す方法だけを盲目的に保管します。リファレンスホルダー(boost::ref
)としてローカル変数への参照を渡すと、実際にこの参照が格納され、関数が呼び出される前にスコープから外れてしまうと、このバグを見つけるのが困難になることがあります。
これにもかかわらず、私はライブラリの機能を利用することをお勧めします(標準ではstd :: functionとstd :: bindがありますが、lambdaがコンパイラの間で標準になるときは、 )。
コールバック機能: Callback functions in c++
http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.../c10557
仮想関数: http://en.wikipedia.org/wiki/Virtual_function
これらはあなたがグーグルによって取得結果です!追加するものはそれ以上ありません。コールバック関数と仮想関数の違い以外は何もないと思います。
コールバック関数は、プログラムの他の部分から参照されるものです。オブジェクトへのポインタをどのように渡すことができるか考えてください。同じことは関数で行うことができます。しかし、これは初心者のプログラマーにとって挑戦的な話題と考えることができます。
仮想関数は、子クラスによって実装できる関数を指します。期間polymorphismを読んでください。
コールバック関数は、別の場所で実行される可能性のあるパラメータとして渡す関数です。
仮想関数は、C++の多態性のビルディングブロックの1つです。つまり、このメソッドを基本クラスのオブジェクトで呼び出すと、継承チェーンの最上位の派生クラスから同じメソッドが呼び出されます。
コールバック関数はトレースするのが難しいですが、時には非常に便利です。特にライブラリを設計しているとき。コールバック関数は、ユーザーに関数名を与えるように要求するもので、特定の条件下でその関数を呼び出すことができます。
void cbfunc()
{
printf("called");
}
int main()
{
/* function pointer */
void (*callback)(void);
/* point to your callback function */
callback=(void *)cbfunc;
/* perform callback */
callback();
return 0;
}
virual関数は、関数をオーバーライドすることによって多型を達成するために使用されることを意味します。
コールバック関数は、制御の反転(重要なデザインパターン)を実装しています。仮想関数は多態性(プログラミングパラダイム)を実装します。基本的には、コードは2つの異なる角度から見えるという意味で無関係です。制御の反転を実装する1つの方法は、仮想関数が効果的にコールバック関数になる抽象基本クラスを使用する方法です。しかし、用語コールバック関数を聞くときのほとんどの場合、抽象基本クラスと仮想関数を使用できないC言語で定義されたAPIに関するものです。そのような場合は、フリー関数(通常extern "C"
)が必要です。ほとんどの場合、この関数はvoid*
引数を受け取ってデータを渡すことができます。
extern "C"は関数のプロトタイプではなく名前のマングリングと関係があります。それ以外はあなたの答えはかなり良いです。 – CashCow
@CashCow 'extern" C "'は、名前のマングリングが一部に過ぎない呼び出し規約を指定します。関数が 'extern" C "'であるかどうかは、その型の一部です。コンパイラが 'extern" C++関数を引数として 'extern" C "'を必要とする関数に渡すことを許可していれば、それは標準に準拠していません。 'pthread_create'のような関数は、渡された関数を' extern "C"(少なくとも標準を適用するコンパイラで)必要とします。 –
- 1. 抽象関数と仮想関数
- 2. 仮想基本クラスから継承する仮想関数の「仮想サンク」とは何ですか?
- 3. 純粋な仮想関数のないC++抽象クラス?
- 4. 仮想関数は、基本クラスの同じ名前の非仮想関数をオーバーライドしますか?
- 5. 抽象基本クラスメンバ関数から純粋仮想関数を呼び出しますか?
- 6. 基本クラスのプライベート仮想関数にアクセスする方法
- 7. コールバック関数と正規関数の違いは何ですか?
- 8. フォース呼び出し、基本クラスの仮想関数
- 9. 抽象基本クラスと派生クラスのファクトリ関数の戻り値型
- 10. 仮想関数の使用
- 11. 抽象クラス/関数のコンパイルエラー
- 12. C++純粋仮想関数を持つ抽象クラスの子をインスタンス化する
- 13. 本当に仮想関数は何ですか?
- 14. テンプレートベースの派生クラスを持つ基本クラスの純粋仮想関数
- 15. 抽象基本クラスで@autowiredを使用
- 16. 抽象基本クラスからのオーバーロードされた関数の処理
- 17. Versionプロパティで抽象基底クラスSession.Lockと抽象基本クラス
- 18. 仮想関数オーバーライド仮想関数
- 19. はCefRequesthandlerクラスの仮想関数C++
- 20. C++ - エラー:基本クラス仮想関数の不完全型へのメンバアクセス
- 21. 基本クラスへの参照を通じて仮想関数を呼び出す
- 22. 派生クラスのメンバー関数は、基本クラスから仮想を継承していますか?
- 23. ハンドラとコールバック関数の違いは何ですか?
- 24. C++:非仮想関数で純粋仮想関数を使用する
- 25. C++の疑似仮想関数とは何ですか?
- 26. Moq、抽象クラスと仮想プロパティ
- 27. 親クラスの親の仮想関数
- 28. 子クラスの仮想関数のオーバーロード
- 29. 純粋仮想関数でC++クラスを使用するには?
- 30. 仮想関数クラスのメンバ関数内で呼び出し
新しいプログラマとして、尋ねる前にgoogleにとって非常に重要です。 :) – ghostCoder
すべての必要な答えは、グーグルで見つけることができます!私たちができるのは、リンクを提案することだけです。質問に答えない –
私はあなたのために質問をreworded – CashCow