将类方法与函数指针进行比较

Compare class method to function pointer

本文关键字:比较 指针 函数 类方法      更新时间:2023-10-16

我有一个基类(ThinkFunc),其他类从中继承。Func() 是一个虚拟的 void 方法。

我希望能够确定类的类型,所以我认为可以快速轻松地看到 Func() 指向的方法。所以我正在尝试比较函数指针。但显然下面的代码是不允许的。有没有办法在C++子类化虚函数中做到这一点?

bool found = false;
ThinkFunc *tfNode;
for (tfNode = this->thinkfuncs; tfNode; tfNode = (ThinkFunc*)tfNode->next)
{
    if (tfNode->Func == &Thinkers::GroupBoxBouncePan::Func)
    {
        found = true;
        break;
    }
}

获取虚拟方法的地址通常会导致获得蹦床或"thunk"的地址,而不是实际方法的地址。为什么不按如下方式使用dynamic_cast

bool found = false;
ThinkFunc *tfNode;
for (tfNode = this->thinkfuncs; tfNode; tfNode = (ThinkFunc*)tfNode->next)
{
    if (dynamic_cast<Thinkers::GroupBoxBouncePan*>(tfNode) != null)
    {
        found = true;
        break;
    }
}

如果你不想这样做,我建议按照WhozCraig的建议实现某种IsA功能。

在C++语言中,如果涉及的指针中至少有一个指向虚拟方法,则未指定方法指针比较的结果。换句话说,不能使用此方法来确定对象的动态类型。

原因是C++方法指针是"多态的":它们绑定到虚拟方法的特定版本很晚,在调用的那一刻,而不是早,在初始化的那一刻。为了实现此行为,使用虚拟方法的地址初始化的方法指针的物理值实际上是某些中间"调度程序"代码的入口点。(这是一种可能的实现。存在替代实现。该中间代码应该执行正确的虚拟调度,具体取决于调用中使用的对象的动态类型。中间代码可以由完全不相关的虚函数共享。这样做的实际结果是,指向完全不相关的虚函数的方法指针可能比较相等。语言规范只是说这种比较的结果是未指定的。

允许人们确定多态对象的动态类型的语言功能是typeiddynamic_cast

您可以在每个子类上都有一个 const static std::string TYPE 成员(例如,使用一个包含子类名称的字符串)和一个返回该 TYPE 成员的 virtual std::string getType() 方法。这样,您可以比较指针返回的值:

ThinkFunc.h

class ThinkFunc{
    public:
    virtual const std::string& getType();
};

GroupBoxBouncePan.h

namespace Thinkers{
    class GroupBoxBouncePan{
        public:
        static const std::string TYPE;
        virtual const std::string& getType(); // returns TYPE
    };
};

群盒弹跳潘.cpp

const std::string Thinkers::GroupBoxBouncePan::TYPE = "Thinkers::GroupBoxBouncePan";
const std::string& Thinkers::GroupBoxBouncePan::getType(){
    return TYPE;
}

搜索将是这样的:

bool found = false;
ThinkFunc *tfNode;
for (tfNode = this->thinkfuncs; tfNode; tfNode = (ThinkFunc*)tfNode->next)
{
    if (tfNode->getType() == Thinkers::GroupBoxBouncePan::TYPE)
    {
        found = true;
        break;
    }
}