我有一个其他类继承的基类(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;
}
}
答案 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>初始化时刻。为了实现这种行为,用虚拟方法的地址初始化的方法指针的物理值实际上将是某些中间“调度程序”代码的入口点。 (这是一种可能的实现。存在替代实现。)该中间代码应该执行适当的虚拟分派,具体取决于调用中使用的对象的动态类型。中间代码可以由完全不相关的虚函数共享。其实际结果是指向完全不相关的虚函数的方法指针可能比较相等。语言规范只是说这种比较的结果是未指定的。
允许用户确定多态对象的动态类型的语言功能是typeid
和dynamic_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;
}
}