我有一个基类:
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/