c++ - 基类到派生类的类型转换

标签 c++ class dynamic casting

我有一个基类:

class RedBlackTreeNode
{
// Interface is the same as the implementation
public:
    RedBlackTreeNode* left;
    RedBlackTreeNode* right;
    RedBlackTreeNode* parent;
    Color color;
    TreeNodeData* data;

    RedBlackTreeNode():
        left(0),
        right(0),
        parent(0),
        color(Black),
        data(0)
    {
    }
    // This method is to allow dynamic_cast
    virtual void foo()
    {
    }
};

以及从中派生出的一个:

class IndIntRBNode : public RedBlackTreeNode
{
public:
    IndIntRBNode* left;
    IndIntRBNode* right;
    IndIntRBNode* parent;
    IndexedInteger* data;
    IndIntRBNode():
        RedBlackTreeNode(),
        left(0),
        right(0),
        parent(0),
        color(Black),
        data(0)
    {
    }
};

root() 和 rootHolder 在 RedBlackTree 类中定义:

class RedBlackTree 
{
public:
    RedBlackTreeNode rootHolder;
    RedBlackTreeNode* root()
    {
        return rootHolder.left;
    }
    ...
}

然后我尝试进行类型转换:

IndIntRBNode *x, *y, *z;

z = dynamic_cast<IndIntRBNode*>(root());

而“z”只是变成了一个零指针,这意味着类型转换失败了。 那么它有什么问题,我该如何修复它才能将“z”引用为指向 IndIntRBNode 的指针?

补充:rootHolder.left 的初始化是这样的:

    int n = atoi(line + i);

    tree.clear();
    int j = 0;
    if (n > 100)
    {
        n = 100;        // Maximum 100 nodes
    }
    while (j < n)
    {
        IndexedInteger num(j,j + 10);
        RedBlackTreeNode* node;
        int c = tree.search(&num, tree.root(), &node);
        if (c != 0)
        { // if value is not in the tree
            IndexedInteger* v = new IndexedInteger(num);
            tree.insert(node, v, c);
            ++j;
        }
    }

换句话说,它是在“insert”方法的“while”的第一次迭代中以这种方式初始化的:

void RedBlackTree::insert(
    RedBlackTreeNode* parentNode,
    TreeNodeData* v,
    // If it's negative, then add as the left son, else as the right
    int compare
)
{
    assert(parentNode != 0 && compare != 0);
    RedBlackTreeNode* x = new RedBlackTreeNode;
    x->data = v;
    x->parent = parentNode;
    // If it's root
    if (parentNode == &rootHolder)
    {
        // Then it must be black
        x->color = Black;
    }
    else
    {
        // Leaf must be red
        x->color = Red;
    }
    if (compare < 0)
    {
        // Insert the node as the left son
        assert(parentNode->left == NULL);
        parentNode->left = x;
    }
    else
    {
        // Insert the node as the right son
        assert(parentNode != &rootHolder && parentNode->right == NULL);
        parentNode->right = x;
    }

    ++numNodes;

    if (x != root())
    {
        rebalanceAfterInsert(x);
    }
}

实际上是问题所在:“插入”动态创建了 RedBlackTreeNode,所以它不可能是 IndIntRBNode。 我真的把它初始化错了,但是我怎样才能派生基类而不是为了改变类型而从头开始编写它的整个实现呢? 我真的必须重写派生类中的所有“类型相关”方法吗?这似乎很愚蠢,我认为应该有另一种方式 - 类派生和类型转换的东西,不是吗?

最佳答案

你确定RedBlackTree::rootHolder.left已经初始化了吗?

我认为您在某个地方初始化了 IndIntRBNode::left,但是当您访问 RedBlackTree::rootHolder.left 时,您访问的是 RedBlackTreeNode::left,这不是同一个字段。

关于c++ - 基类到派生类的类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1274912/

相关文章:

php - 从存储在变量中的字符串中获取对象数据

batch-file - 使用动态名称调用多行宏?

c++ - 将所有内容都放在 QApplication 的子类中有意义吗?

python - 多继承python问题

c++ - 析构函数 : triviality vs implicit definition

Php 从不同的类运行时扩展(扩展为变量?)

PHP/MySQL 重新排序菜单,在表中设置位置

c# - C#中使用反射调用方法时如何自动对参数进行类型转换?

c++ - 未定义的 vtable 引用,Linux 中的 Qt

c++ - 有人可以验证红黑树后继者是否编写正确吗?