• 締切済み

C#のdelegateをC++とjavaで?

C#のデリゲードを javaとC++でできないでしょうか。 ただし、質問内容を勘違いされそうなので、求めている内容と、 求めていない内容を、詳しく 書きますと。 インタフェース委譲を使った例は、求めていません。 あらかじめ、委譲先に静的に仕組みを 作っておかなく手も、C#のデリゲードのように、シグニチァが同じなら 委譲先をはめ込めれるのが欲しいです。 単なる関数ポインタの例は、求めて いません。 C#でdelegate型を引数にとる ところに、あるインスタンスの メソッドを渡すと。 どのインスタンスのどのメソッドかまで、 認識して、コールバックできます。 関数ポインタでは、これができない。 STLの関数オブジェクトとか、古い感じの情報にヒントがあるか。調べてみましたが。よくわかりませんでした。 結局、この関数オブジェクトは、僕が求めているモノとは、違うような気がします。 よくわかりませんが。 欲しいのは、どのインスタンスのどのメソッドかまでを特定して、 記憶できる型をどうやって javaや、C++で実装できるか。 それをインタフェース委譲のように、 委譲先にあらかじめ、仕込んでおくことなしに。 ただ、メソッドのシグニチァが同じであるだけで、どのインスタンスのどのメソッドかまでを特定して記憶できる C#のデリゲードのような型を。 特殊なコンポーネントを利用せず。 標準的な言語構文のみをつかって、 どのようにしたら、 javaや、C++で、実装できるか? です。 詳しい方が、いらっしゃいましたら、 教えてください。

みんなの回答

回答No.4

> [&obj1](int x, int y){ return obj1.add(x,y);}は、 > 新たに、ラムダ式のようなものを作って、 > delgに指定してるようにみえるです "ようなもの"じゃなく、これがC++のラムダ式です。 > obj1のaddを直で、取得し、その上記の型の変数や引数で > 受けることは。 > C++の標準的な構文では、不可能なのでしょうか? 直接取得するのは無理。あえてやるなら #include <iostream> #include <functional> using namespace std; class foo { int base; public: explicit foo(int b) : base(b) {} int add(int x, int y) const { return base + x + y; } // ↓ラムダ式を返すメソッド function<int(int,int)> add_delg() const { return [this](int x, int y) { return add(x,y); }; } }; int main() { function<int(int,int)> delg; // delegate int delg(int,int) foo obj1(1); foo obj2(2); delg = obj1.add_delg(); cout << delg(2,3) << endl; delg = obj2.add_delg(); cout << delg(2,3) << endl; }

meviusjp
質問者

補足

素晴らしいです。 なんでもできるんですね。 天才的な人だ。 add_delg みたいなのが、まさに、それ。 C#の場合は、メソッドそのものが、 直でdelegateに指定できて、 メソッドそのものが、もう デリゲードそのもののように 見えるんですが。 C++では、 ラムダ式の形をとらないと。 『どのインスタンス』か? という情報をもったものを 取得する手段がないということですか。 [this]という構文が このインスタンスです、といって、 そのロジックが、 (int x,int y) { return add(x,y);} ですといってようです。 昔、メンバー関数を、関数ポインタに 指定しようとして、 コンパイラに怒られて、 あぁ、無理なのか。 そういえば、メンバー関数は どのインスタンスか? という情報もあるし。 別物なんだろなと、 思ってたです。 メンバー関数に、直でコールバックするのってどうするんだろ。 って、おもったまま、 今回の回答をもらうまで、 ずっと、わからなかったです。  functin<int(int,int)> 中身がどうなってるか 不思議だけど、 勉強になったです。

  • KSOH
  • ベストアンサー率93% (29/31)
回答No.3

Javaだと以下のような記述になると思います。 例:C# MyClass instance = ... delegate int Foo(int a, int b); Foo d = new Foo(instance.method); int result = d(1, 2); 例: Java(Java8以降) import java.util.function.BiFunction MyClass instance = ... BiFunction<Integer, Integer, Integer> d = (a, b) -> instance.method(a, b); int result = d.apply(1, 2); なお引数の個数が0~2の場合はjava.util.functionパッケージの定義済みインターフェースを利用できますが、個数が3つ以上のものは個数毎に個別のインターフェースを自前のライブラリーなどに定義することになります。

meviusjp
質問者

補足

ありがとうごさいます。 No.2のC++の回答も、 No.3のjavaの回答も、 ラムダ式的なもので、 このインスタンスのこのメソッドを 呼ぶようなコードを書いて。 それをfunctin的なシグニチァと戻り型だけを定義した型で受けて コールバックする感じのようですね。 これだと、この受けてる型自体には、 どのインスタンなのかという情報ないですが、ラムダ式の実装で、どのインスタンスのどのメソッドかをかけば。 実際問題、不便ではない。 どうせ、C#でも、そのデリートに 値を指定する部分で、 obj.addというのを書いて。 このインスタンスのこのメソッドを 渡すとかくのだから。。 C#のデリートが特殊で No.2, 3のほうが実は標準的な感じに みえたです。 C#のデリートが、すごく便利なので、 おんなじこと、できんだろか。 前々から、思ってたので、勉強になったです。 javaも8は、ラムダ式かけるんですね これも、知りませんでした。 No.2の最後で回答の補足で、 した欲張った質問は、 ちょっと、ムリそうな感じではと 思われるです。 僕は、ちょっと、勉強が足りないです。 BiFunctinの中身のソースコードが どうなってるか想像つかない。 ラムダ式ようなものを、C#のデリート以外の方法で受ける手段としての インタフェースを定義 できるということすらわかってなかったです。 3つ以上の引数バージョンのインタフェースの実装の想像がつかない。 でも、無知な部分が何かが、 浮き彫りになって、 とても、意味があったです。

回答No.2

> aのfooと、bのbarにそれぞれきちんと > 区別してコールバックできるのでしょうか。 #include <iostream> #include <functional> using namespace std; class foo { int base; public: explicit foo(int b) : base(b) {} int add(int x, int y) { return base + x + y; } }; int main() { function<int(int,int)> delg; // delegate int delg(int,int) foo obj1(1); foo obj2(2); delg = [&obj1](int x, int y) { return obj1.add(x,y); }; cout << delg(2,3) << endl; delg = [&obj2](int x, int y) { return obj2.add(x,y); }; cout << delg(2,3) << endl; } > function<int,int>は、なぜ、 > intを返すのでしょうか? function<int,int> ではありません、function<int(int,int)> です。

meviusjp
質問者

補足

さっそく、ありがとうごさいます。 こんな質問にまともに、回答できるとは、 おそらく、スゴ腕な人ではないかと 思うです。 基本的なことを確認したいのですが。 &obj1がobjのアドレスでしょうか。 この場合の[ ]の記号は どういう意味をもっているのでしょうか? それで、 [&obj1](int x, int y){ return obj1.add(x,y);} は、 新たに、ラムダ式のようなものを 作って、 delgに指定してるようにみえるです この方法だと、大枠、求めてるものに 近く見えるです。 確かに、obj1のaddと、obj2のaddを うまく呼びわけてるです。 すごいです。 欲張ったように質問して すいませんが。 特定のインスタンスの特定メソッドを 表すオブジェクトの型、 つまり、C#のデリートに そっくりな型を実装し、 obj1のaddを直で、取得し、 その上記の型の変数や引数で 受けることは。 C++の標準的な構文では、不可能なのでしょうか?

回答No.1

#include <iostream> #include <functional> using namespace std; int main() { function<int(int,int)> delg; // delegate int delg(int,int) delg = [](int x, int y) -> int { return x+y; }; // x,y => x+y //delg = [](int x, int y) -> char* { return (char*)"hello"; }; // error cout << delg(2,3) << endl; } こんなのですか? # Javaはわからんです

meviusjp
質問者

お礼

もう少し、わかりやすく、 求めている内容を補足すると。 C#のデリートのように、 インスタンスのメソッド(メンバー関数) を指定できるか。という点。 単なる関数ポインタのように、 どのクラスにも、属さない グローバルな位置にある関数を 受けれる とか、クラスに属していても、 特定のインスタンスにひもづいていない、 staticな関数を受けれる とか、そういうのではなく、 ある特定のインスタンスのメソッド(メンバー関数)を受けれて。 そのインスタンスのそのメソッドへコールバックするようにできないか? ということです。 インスタンスは、その時の状態をもっているので、それぞれのインスタンスを区別して指定したメソッドへコールバックしたいのです。 そして、その時、できれば。 (可能であればですが。) #include <functional> のように、環境によっては、利用できないかもしれないものをできるだけ利用せず、 言語が持ってる標準的な構文だけで、 C#のデリート型のような型を実装する方法が、あれば。 そこを求めています。

meviusjp
質問者

補足

さっそく、ありがとうごさいます。 普通の関数ポインタのような 使い方のように見えますが。 function<int,int>が 僕には詳しくわからないのですが。 private method(function<int, int> argcallback) { int ret = argcallback(2,3); return ret; } というものにたいして、 intを2つ引数にとりintを返すfooメソッドを持つ型のインスタンスaと、 intを2つ引数にとりintを返すbarメソッドを持つ型のインスタンスbとがあり、 a, bが異なる型であったとします。 このとき。 method(a.foo); method(b.bar); と書いた時、 aのfoo と、bのbarにそれぞれきちんと 区別してコールバックできるのでしょうか。 僕が求めているのは、そこで、 どのインスタンスのどのメソッドかを記憶できるか?という点 補足で、質問あるですが。 function<int,int>は、なぜ、 intを返すのでしょうか? delegate int delg(int,int) が、コメントでかいてありましたので。

関連するQ&A

  • Cに慣れてしまった人、どのようにJAVAを克服しましたか?

    JAVAについて質問です。 私はC言語をこの1年間勉強してきました。 そしてC言語のコーディングの仕方に慣れきってしまったせいか、どうしてもJAVAのオブジェクト指向 というものが理解できません。 コーディングも上手くいきません。 クラスやメソッドやインスタンスがどうとかコンストラクタが・・・などの横文字が全然意味が分かりません。 C言語で言うとどれがどこに当たるのか!? とかいう風に置き換えて考えようとしても上手く行きません。 こういう、横文字が理解できて、オブジェクト指向の考え方に慣れる為にはどのようにしたらいいでしょうか? また、C言語からプログラミングに入って、後からJAVAを勉強する場合、どのような点に気をつければ良いでしょうか? また、JAVAの克服法を教えてください。

    • ベストアンサー
    • Java
  • RubyでJavaのInterfaceに相当するものはありますか?

    RubyでJavaのInterfaceに相当するものはありますか? Ruby 上で Javaの interface のようなものものを実現するには、どうしたらよ いのでしょうか? Rubyは型を宣言しないので機能的には interface は不要ですが。 クラスを実装する人に、あるクラスに実装しなければいけないメソッドを伝える (強制する)目的としての interface 的な使い方をしたいのです。 宜しくお願いいたします。

  • インターフェイスの使い方がわかりません(初心者です)

    Javaを始めたばかりの初心者です。 「やさしいJava」を買って一通り学んだのですが、 インターフェイスの使い方がよくわからず、困っています。 インターフェイスを実装することでインターフェイスが持つメソッドがすべて定義されてることが保障される、 というのはわかるんですが、そのことがどうして有用なのでしょう? また、具体的にはスレッドを扱うときにRunnableインターフェイスを実装する理由がわかりません。 Threadクラスのオブジェクトを作成するときに、 Runnableを実装したクラスのオブジェクトの変数を 引数にしないといけないんですよね? このとき、Runnableインターフェイスが 「runメソッドが定義されていなければならない」 とだけいうものだったとしたら、 Runnableを実装してなくてもrunメソッドさえ定義してあれば 実行できそうな気がするんですが・・・

    • ベストアンサー
    • Java
  • javaに"search"という関数 or メソッドはあるのでしょうか?

    javaに"search"という関数 or メソッドはあるのでしょうか? webサイトで探しても見つかりません。 出てくるのはExcelのsearch関数が出てきます。 もし、Javaに"search"関数 or メソッドがあるならば、どのような 機能(働き)なのでしょうか? Javaで"search"を見かけたのは、 こういった文です。 *********************************** AAA:クラス a:インスタンス(オブジェクト) b:インスタンス(オブジェクト) eee:データベースのPrimaryキー fff:データベースのPrimaryキー AAA a = b.serch(eee, fff); if(a = null) { ・・・・・省略・・・・・ } ************************************ また、searchについてwebサイトがあれば 教えて頂きたいのですが、 どなたか宜しくお願いします。

    • ベストアンサー
    • Java
  • JavaからCへ

    僕は今までJavaを勉強していたのですが、 つい最近になって、C言語に手をつけ始めました。 Javaを知っていればC言語は結構とっつきやすいのではないかと思って始めたのですが、Javaに慣れすぎたせいか、C言語の文法がどうもしっくりきません。 特に関数あたりが・・・・。 C言語の関数って、Javaでいうところのメソッドですよね? 僕はそのように解釈しているのですが、あまり自信がないので、ご存知の方がいましたらどなたか教えてください。 あと、Javaを学習した人のためのC言語の本、もしくはC言語を学んだ人のためのJavaの本がありましたら教えてください。

    • ベストアンサー
    • Java
  • JAVAでCの関数ポインタのようなことをするには?

    CのプログラムをJAVAに移植しています。関数ポインタのプログラムを移植したいのですがやり方がよく判りません。interfaceを実装するとできるようですが・・・ 以下のCプログラムをJAVAに移植する方法を教えてください。 #include <stdio.h> int func(int , int); int main() { int (*po)(int , int) , i; po = func; i = (*po)(10 , 3); printf("%d" , i); return 0; } int func(int i , int j) { return i + j; }

    • ベストアンサー
    • Java
  • JNAで関数ポインタの表し方

    JNAで関数ポインタの表し方 JNAを利用してC言語の関数をJavaで利用したいのですが、その関数の引数に関数ポインタが含まれていて、使い方が分かりません。 関数ポインタ型のJavaのマッピングはどうすればいいのでしょうか? つまりJavaの特定のメソッドをその関数内からコールバックさせたいです。

  • c# インターフェイスの実装の確認

     こんにちは。c#初心者です。  EqualityComparer<T>.DefaultプロパティはT型がIEqualityComparer<T>インターフェイスを実装しているか確認する操作を含むようですが、それと同じようにインスタンスなしでT型が特定のインターフェイスを実装しているかどうか確認したいのですが、可能なのでしょうか?  どなたか詳しい方がいらっしゃいましたら教えてください。

  • ADODB.Connectionはインターフェイス

    いつもお世話になっております。 C#で特定のDBに接続するクラスを作ろうとADODB.Connection(ADO.Conn)を継承しようとしたところADO.Connはインターフェイスであるため、各メンバの実装をしなくてはなりません。ADO.Connはオブジェクトととしてインスタンスを生成できていたため、なぜインターフェイスがインスタンスを生成してオブジェクトとして使えるのかがわかりません(Excel.Applicationなども同様です)。 これはどのような仕組みになっているのでしょうか?

  • 継承・実装の関係で悩んでいます。

    継承・実装の関係について悩んでいます。 ここでは、アクセス制御を考えずに、インスタンスかstaticかabstract(ここではabstract final staticやabstract classのこと)の違いで、どう継承するのか考えています。 // 継承 はメソッドのオーバーライドのことを考えます。(オーバーロードは考えない) クラスAからクラスBでオーバーライドしたメソッドは、 クラスCでさらにオーバーライドできるのでしょうか? クラスCが クラスBのクラスAからオーバーライドしたメソッド をクラスBのメソッドとして見たときに、オーバーライドすることは可能なのでしょうか? クラスA │ インスタンスフィールドA │ staticフィールドA │ │ クラスA() { } │ │ インスタンスメソッドA () { } │ staticメソッドB() { } ↓ クラスB extends クラスA │ インスタンスフィールドA // 継承 │ インスタンスフィールドB │ staticフィールドB │ │ サブクラス1() { } // コンストラクタは継承しない、super()で呼び出す │ │ インスタンスメソッドA () { } // 継承 │ │ インスタンスメソッドB () { } │ staticメソッドB () { } ↓ クラスC extends クラスB implements インタフェースD, ... ↑ インスタンスフィールドA // クラスBのフィールドを継承 │ インスタンスフィールドB // クラスBのフィールドを継承 │ インスタンスフィールドC │ staticフィールドC │ │ サブクラス2() { } │ │ インスタンスメソッドA () { } // クラスBのメソッドを継承 │ インスタンスメソッドB () { } // クラスBのメソッドを継承 │ インスタンスメソッドD () { } // インタフェースDのメソッドを実装 │ インスタンスメソッドE () { } // インタフェースDのメソッドを実装 │ │ │ インスタンスメソッドC () { } │ staticメソッドC() { } │ interface インタフェースD extends インタフェースE ↑ │ staticフィールドD // public static final │ │ インスタンスメソッドD() { } // public abstract │ インスタンスメソッドE() { } // 継承 │ interface インタフェースE staticフィールドE // public static final インスタンスメソッドE() { } // public abstract

    • ベストアンサー
    • Java

専門家に質問してみよう