3

我有一个小问题。

function PointerC++ 中与delegateC# 中的行为相似吗?

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++'s 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# 的委托是处理函数指针的类类型。函数指针只是一个 32 位或 64 位无符号整数,它指向相关函数所在的内存中的特定位置。在 C++ 中,您只有一个原始的、非托管的函数指针。

于 2013-07-11T04:53:49.833 回答
0

从本质上讲,是的,但代表要丰富得多。函数指针只是指向函数所在内存的指针。委托是包装函数指针和其他信息的类。

因为基本上 C# 中的所有内容都是一个类,所以委托可以指向一个类上的方法。在 C++ 中,这是一个真正的痛苦,因为 C++ 函数使用特殊的调用约定来调用类方法,并且函数指针本身不存储指向对象的指针(您必须单独维护它)。

委托也可以链接在一起,并且比 C++ 函数指针具有更大的类型灵活性。请参阅委托中的协变和逆变

于 2013-07-11T04:39:53.063 回答