C++多态性:有没有办法找到对象成员函数的地址?

C++ polymorphism: Is there any way to find the address of an object's member function?

本文关键字:成员 对象 函数 地址 多态性 有没有 C++      更新时间:2023-10-16

如果我有一个纯虚拟基类,它有几个派生…

class Base
{
public:
virtual void method1() = 0;
}
class Derived1 : public Base
{
public:
void method1() override { ... }
}
class Derived2 : public Base
{
public:
void method1() override { ... }
}

持有未知派生类型对象的Base*的代码是否有任何方法来确定其持有Base*指针的对象的method1()函数的地址?

我想做的是这样的事情:

void someOtherFunction(Base * pb)
{
printf("If I call pb->method1(), it will call a function at %p.n",
&(pb->method1));
}

但我得到了一个编译器错误:

错误:ISO C++禁止获取绑定成员函数的地址以形成指向成员函数的指针。

理想情况下,任何解决方案都会避免RTTI&dynamic_cast,因为我的嵌入式系统不允许这样做。

您要查找的是指向(虚拟(成员函数的指针。请注意,这样的指针不是函数的地址,而是vtable内部的偏移量,因为实际调用的函数取决于对象的实际类型。您甚至不能将此指针强制转换为void*,表示形式是由实现定义的这也意味着您找不到将以通用方式调用的实际函数的地址

如果您真的需要知道要调用的目标函数,那么使用几个单独的函数和一个枚举可能会更好?

无论如何,如果你只想通过指针调用虚拟成员函数,你可以这样做:

void someOtherFunction(Base* pb)
{
using func_t = void(Base::*)(); // Type of a pointer to member function of
// signature void() and object type Base
func_t fn = &Base::method1; // Take the address of the function
(pb->*fn)(); // Call it. Note the extra parenthesis and the operator: ->*
// The actual function called depends on the actual type of pb,
// it can be Derived1::f() or Derived2::f() in the example code you have
}

在不知道自己想要完成什么的情况下,很难给出建议。我会选择以下选项:使用lambdas。

例如,捕获和非捕获:

Base* b = ...;
// non capturing, convertible to function pointer
auto lambda1 = [](Base*) { b->method1() }
auto fptr = static_cast<void(*)(Base*)>(lambda1);
lambda1(b);
fptr(b);
// capturing
auto lambda2 = [b]{ b->method1() };
lambda2();
// can be stored in a std::function if you need them in a collection
std::function func = lambda2;