我有一个小问题。
在function Pointer
C++ 中与delegate
C# 中的行为相似吗?
是的,它们很相似。
但是 C++ 中的函数指针不能指向类的实例方法,而 C# 中的委托可以。
.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).
是的,C# 的委托是处理函数指针的类类型。函数指针只是一个 32 位或 64 位无符号整数,它指向相关函数所在的内存中的特定位置。在 C++ 中,您只有一个原始的、非托管的函数指针。
从本质上讲,是的,但代表要丰富得多。函数指针只是指向函数所在内存的指针。委托是包装函数指针和其他信息的类。
因为基本上 C# 中的所有内容都是一个类,所以委托可以指向一个类上的方法。在 C++ 中,这是一个真正的痛苦,因为 C++ 函数使用特殊的调用约定来调用类方法,并且函数指针本身不存储指向对象的指针(您必须单独维护它)。
委托也可以链接在一起,并且比 C++ 函数指针具有更大的类型灵活性。请参阅委托中的协变和逆变