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

时间:2013-09-11 17:01:56

标签: c++

我有一个其他类继承的基类(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;
    }
}

3 个答案:

答案 0 :(得分:1)

获取虚拟方法的地址通常会导致获得蹦床的地址或"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功能。

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

您可以在每个子类上拥有const static std::string TYPE成员(例如,使用包含子类'name的字符串)和返回该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
    };
};

GroupBoxBouncePan.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;
    }
}