0

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

3 回答 3

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

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

于 2013-09-11T17:23:56.610 回答
1

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

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

允许确定多态对象的动态类型的语言特征是typeiddynamic_cast

于 2013-09-11T17:36:15.697 回答
0

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

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;
    }
}
于 2013-09-11T18:11:43.587 回答