3

ちょっとした質問があります。

C++ の動作はC#function Pointerと似ていますか?delegate

4

4 に答える 4

3

はい、似ています。

ただし、C++ の関数ポインターはクラスのインスタンス メソッドを指すことはできませんが、C# のデリゲートは可能です。

于 2013-07-11T04:31:05.433 に答える
1

.NET デリゲートは状態を持つことができます。つまり、オブジェクトのインスタンス メソッドへのデリゲートを作成し、デリゲートthis内に保存することができます。

Foo f;
BarDelegate d = f.Bar;
d(); // stores f as 'this' pointer.

関数ポインターは、非メンバー関数を指す場合、デリゲートと同じ使用法を持ちます。軽量であるため (割り当てが不要)、実際にはデリゲートよりも優れていると言えます。

ただし、関数ポインターには状態がありません。これにより、メンバー関数で使用する場合に大きく異なりthisます。関数ポインターを呼び出すときに渡す必要があります。

Foo f;
BarPtr p = &Foo::Bar;
(f.*p)(); // need to pass in 'this' pointer. ugly call syntax!

C++ には「ファンクター」もあります。これは、状態を持つことができ、関数のように呼び出すことができるオブジェクトです。これは、テンプレート化された関数を呼び出すときにデリゲートの代わりに最もよく使用されます。しかし、ファンクタは単なる型の概念であり、実際の型ではありません:

struct BarFunctor
{
    void operator()();
};

BarFunctor f;
f(); // not even a pointer, it's a full object and you're calling it.

.NET デリゲートの機能を正確に複製するためのより適切な比較は、C++ のstd::functionである可能性があります。これは、特定の呼び出しシグネチャで他のファンクターをラップできるファンクターです。ただし、std::functionデリゲートのようにオーバーヘッドがあり、テンプレートによってそのような重いオブジェクトが不要になることが多いため、あまり使用されません。

Foo f;
std::function<void()> func = [&] { f.Bar(); }; // the lambda object (a
func();                                        // functor) capturing a
                                               // reference to f is
                                               // stored into func (also
                                               // a functor).
于 2013-07-11T05:09:57.607 に答える
0

基本的にはそうですが、デリゲートの方がはるかに豊富です。関数ポインタは、関数が存在するメモリへの単なるポインタです。デリゲートは、関数ポインターを他の情報と共にラップするクラスです。

C# では基本的にすべてがクラスであるため、デリゲートはクラスのメソッドを指すことができます。C++ では、C++ 関数は特別な呼び出し規則を使用してクラス メソッドを呼び出し、関数ポインター自体はオブジェクトへのポインターを格納しないため、これは非常に苦痛です (それを個別に維持する必要があります)。

デリゲートはチェーン化することもでき、C++ 関数ポインターよりも型の柔軟性が高くなります。デリゲートの共分散と反分散を参照してください

于 2013-07-11T04:39:53.063 に答える
0

そうです、C# のデリゲートは、関数ポインターを処理するクラス型です。また、関数ポインタは、問題の関数が存在するメモリ内の特定の場所を指す 32 ビットまたは 64 ビットの符号なし整数です。C++ では、生のアンマネージ関数ポインターしかありません。

于 2013-07-11T04:53:49.833 に答える