【发布时间】:2009-08-13 22:14:54
【问题描述】:
我有一个基类:
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”的第一次迭代时通过“insert”方法以这种方式初始化的:
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。 我真的把它初始化错了,但是我怎么能派生基类而不是从头开始编写它的整个实现来改变类型呢? 我真的必须重写派生类中的所有“类型相关”方法吗?这似乎很愚蠢,我认为应该有另一种方式 - 类派生和类型转换的东西,不是吗?
【问题讨论】:
-
rootHolder.left是如何初始化的?