如何在运行时为虚函数获取指针的确切类型?

时间:2013-09-30 14:24:49

标签: c++ pointers inheritance

我正在使用C ++虚拟功能。我有一个基类treeNode和两个派生类的splitNode和leafNode。 splitNodes中的一些指针指向其他节点,可以是splitNode或leafNode。在运行时,如何检查指针是指向叶子还是拆分节点,而不改变节点的结构(即,我不想向它们添加任何新函数)。

此致

5 个答案:

答案 0 :(得分:3)

目前尚不清楚为什么要这样做,但您可以使用dynamic_cast

treeNode* theNode = ....;
splitNode sNode* = dynamic_cast<splitNode*>(theNode);
bool isSplitNode = sNode != nullptr;

或只是

bool isSplitNode = dynamic_cast<splitNode*>(theNode);

如果正确使用多态,则不必执行此操作。

答案 1 :(得分:2)

在基类中实现虚拟GetType方法,并在子类中覆盖它。 这是最有效的方式。

记住Open closed principle。你应该利用多态性。

答案 2 :(得分:1)

您可以使用dynamic_casttypeid运算符执行此操作。但是,通常这是一个非常糟糕的主意。如果您的虚函数需要知道对象的确切类型,那么您的设计就会出现问题。

如果您遇到这种情况:

class treeNode
{
  virtual int foo()
  {
    // do some default thing, maybe nothing
  }
};

class splitNode : public treeNode
{
  virtual int foo()
  {
    // do whatever splitNode wants to do
  }
};

class leafNode : public treeNode
{
  virtual int foo()
  {
    // do whatever leafNode wants to do
  }
};

你有一个指向treeNode *p;splitNode对象的指针leafNode,你调用p->foo(),然后调用适当版本的foo()将被调用。这就是虚函数的重点。

另请参阅this question

答案 3 :(得分:0)

拥有枚举成员的类型,或者返回子节点数的虚函数。就个人而言,我只会有一个带有枚举的节点类(或叶子的空子指针)。

答案 4 :(得分:0)

您可以使用typeid运算符获取指向runtime-polymorphic对象的指针的基础类型。这是一个适合您描述的设计的示例:

struct treeNode
{
};

struct splitNode : treeNode
{
    treeNode* left;
    treeNode* right;
};

struct leafNode : treeNode
{
    bool disabled;
};

void traverse(splitNode* node);
void traverse(leafNode* node);

void traverse(treeNode* node)
{
    if(typeid(*node) == typeid(leafNode))
    {
        return traverse(static_cast<leafNode*>(node));
    }
    return traverse(static_cast<splitNode*>(node));
}

请注意dynamic_cast几乎完全相同。

与在基类中存储某种形式的type-id并使用typeid相比,static_cast的性能可能较差。尽管有这些警告,但它对于非性能关键的代码(例如大多数代码)非常有用。