I have a base class:
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()
{
}
};
and a derived from it one:
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() and rootHolder are defined in RedBlackTree class:
class RedBlackTree
{
public:
RedBlackTreeNode rootHolder;
RedBlackTreeNode* root()
{
return rootHolder.left;
}
...
}
Then I'm trying to typecast:
IndIntRBNode *x, *y, *z;
z = dynamic_cast<IndIntRBNode*>(root());
And "z" just becomes a zero-pointer, which means that typecast failed. So what's wrong with it, how can I fix it to be able to reference "z" as pointer to the IndIntRBNode?
Added: the initialization of the rootHolder.left was some kind of that:
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;
}
}
In the other words, it was initialized on the first iteration of "while" by the "insert" method in such way:
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);
}
}
It actually was the problem: "insert" created the RedBlackTreeNode dinamically, so it couldn't be IndIntRBNode. I really have initialized it wrong, but then how can I derive the base class and not write the whole implementation of it from a scratch just to change the types? Do I really have to override all the "type-relative" methods in the derived class? It seems to be very stupid, I think there should be the other way - something with class deriving and typecasting, isn't it?