- ベストアンサー
C++でデリゲート
C#で仕事されている方から質問されたのですが、C++でデリゲートは利用できるのでしょうか? 私はC#を使ったことがなくC++の言語仕様も詳しくないので答えられませんでした。 ざっと話を聞いたところコールバックを手軽に利用できるという印象でした。 本質はC#を勉強してみようと思いますが、C++では利用できるのでしょうか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
○C++ にはデリゲートその物に対応する文法は存在しませんが、等価な機能を実現する方法は色々あります。 a. C++11 以降のラムダ式を用いればデリゲート(オブジェクトインスタンスに紐付いたメンバ関数)と同様の物を簡単に作成できます。 例: struct MyClass{ int instanceMemberFunction(int,int); } obj; auto func = [&obj](int _1,int _2) -> int{return obj.instanceMemberFunction(_1,_2);}; b. 或いは、C++11 以降で標準ライブラリに取り込まれた std::bind, std::placeholders 等を組み合わせるという事もできます。 例: // #include <functional> auto func = std::bind(std::mem_fun(&MyClass::instanceMemberFunction), &obj, std::placeholders::_1, std::placeholders::_2); c. C++03 以前でも、等価な事を実現する為のテンプレートを自分で書くことは勿論できます。 例えば、以下の様にして使える Function/CreateDelegate を作るのはそんなに難しくない(実際 Boost ライブラリの boost::function, boost::bind1st, boost::mem_fun あたりを拡張する様な感じでできるのでは)と思います。 Function<int(int,int)> func = CreateDelegate(&obj, &MyClass::instanceMemberFunction); 一旦この様なテンプレートを書いてしまえば、この方法が一番 C# に近い形で使えるのかなと思います。また、マルチキャストデリゲートの対応も、Function クラスの機能として自然に実装できます。 ○注意点 但し、C++ は C# と違ってガベージコレクションがないので、オブジェクトインスタンスの寿命に気を付けなければなりません。特にローカル変数として宣言したクラスインスタンスはスコープを抜けると(≒関数を抜けると)消えてなくなります。寿命の管理は、多くの場合 C++11 の std::shared_ptr で済ませられると思います(勿論、循環参照などには気をつける必要はあります)。 例: // #include <memory> std::shared_ptr<MyClass> pobj=std::make_shared<MyClass>(); auto func = [pobj](int _1,int _2) -> int{return pobj->instanceMemberFunction(_1,_2);}; 最後に: C# と比べると C++ でデリゲートの機能を利用するのは色々と面倒であり C# 使いから見れば C++ は劣っている様に思われるかもしれません。しかし、自分で色々と指定できる分、柔軟に設計できるのが C++ の強みです。効率的に開発するなら C# で、細部にこだわりたいのであれば C++ で、ということです…
その他の回答 (1)
- Hayashi_Trek
- ベストアンサー率44% (366/818)
検索すれば普通に見つかりますが... http://www7b.biglobe.ne.jp/~robe/pf/pf016.html https://msdn.microsoft.com/ja-jp/library/3z2x4f55.aspx http://qiita.com/rinse_/items/7aca3018caa9a4ebf527 など、多数ある。
お礼
早々のレスありがとうございます。 普通にC++に標準であるのかと勘違いしていました。 リンクはとても参考になります。
お礼
早々のレスかつ詳細な説明をありがとうございます。 C++に標準であるのかな?と勘違いしていました。 ラムダ式もイマイチ分かっていないのでこれもマスターしようと思います。 見よう見まねで実装してみました。それっぽいものはできました。時間のあるときに煮詰めていきたいです。