我有一个基类:
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,这不是同一字段。