C++ 中的"function Pointer"与 C# 中的"delegate"行为相似吗?

is "function Pointer" in c++ similar in behavior with "delegate" in c#?

本文关键字:中的 相似 function Pointer C++ delegate      更新时间:2023-10-16

我有一个小问题。

C++中的function Pointer与C#中的delegate在行为上相似吗?

是的,它们很相似。

但是C++中的函数指针不能指向类的实例方法,而C#中的委托可以。

.NET委托可以具有state,即可以创建对象实例方法的委托,并将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).

本质上是的,但委托要丰富得多。函数指针只是指向函数所在内存的指针。委托是一个将函数指针与其他信息一起封装的类。

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

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

是的,C#的委托是一个处理函数指针的类类型。函数指针只是一个32位或64位的无符号整数,它指向内存中有问题的函数所在的特定位置。在C++中,您只需要一个原始的、非托管的函数指针。