如何从派生 class 访问派生基成员?(在 C++ 中)

How can I access derived base member from derived class?(in C++)

基础 class 是 NodeAvLNode是从中派生出来的

AVLNode中当this->Left()->Height()Balancefactor()调用时, Left() left* from class Node 没有身高被称为。 它以分段错误结束。

基础class:

// A generic tree node class
template<class NodeType>
class Node {
  string key;
  NodeType* left;
  NodeType* right;
  NodeType* parent;
public:
  Node() { key="-1"; left=NULL; right=NULL; parent = NULL;};
  Node(NodeType* source) {  //Copy Constructor
    key=source->Key();left=source->Left();right=source->Right();parent=source->Parent(); 
};
void setKey(string aKey) { key = aKey; };
void setLeft(NodeType* aLeft) { left = aLeft; };
void setRight(NodeType* aRight) { right = aRight; };
void setParent(NodeType* aParent) { parent = aParent; };
string  Key() { return key; };
NodeType* Left() { return left; };
NodeType* Right() { return right; };
NodeType* Parent() { return parent; };
void copyData(NodeType* source){key=source->key;};
};

派生 class:

class AvlNode : public Node<AvlNode>
{
 int height;
 public:
 AvlNode(){height=1;};
 //~AvlNode();
 int Height() { return height; };
 int BalanceFactor(){
    return this->AvlNode::Left()->Height() - this->AvlNode::Right()->Height();
 };
 int setHeight(int aHeight){height=aHeight;};
};

当您创建 AvlNode 时,其构造函数默认初始化其基础 Node。所以 leftright 指针都是空的。

当然,稍后您可能会使用 setLeft()setRight() 更改它,但不能保证您会这样做。同样在树结构中,你总是有没有左边也没有右边的叶子。并不是所有的节点都有左节点和右节点。

因此,对于可靠的代码,您必须考虑 Left()Right() 为 null 的可能性:

int BalanceFactor()
{
int hl=0, hr=0;               // value of height if no child

if (Left()) 
    hl = Left()->Height();    // only dereference the pointer if not null
if (Right())
    hr = Right()->Height(); 

return hl-hr; 
};

非常重要的评论与您的​​问题无关:

您在 github 的评论中提供的代码库包含重要错误:

  • addNode() 中,您并不总是 return 一个值:这可能会导致随机节点指针被 returned,从而导致内存损坏。当你递归调用 addNode(...) 你实际上应该 return (addNode(...)))
  • Tree::min()Tree::max()Tree::findNode() 中的相同错误也适用于递归调用。
  • 最后 Tree::Successor() 不会 return 如果 if 条件的 none 为真,即如果 thisKey 为空)。我在这个函数的末尾添加了一个 return thisKey;

只有更正了这些错误后,我才能运行 没有段错误的代码。这里是 bst.cpp and avl.cpp 的 运行ning 摘录,我不得不更改一行上的感叹号。