我有一个基类:

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


换句话说,它是通过“插入”方法在“ 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,这不是同一字段。

09-10 00:16