如何从派生类访问派生基成员?(C++年)
How can I access derived base member from derived class?(in C++)
Base class isNode
.AvLNode
就是从中衍生出来的。
在AVLNode
,当this->Left()->Height()
被要求Balancefactor()
时,Left()
从没有身高的班级Node
左*被称为。 它最终会出现分段错误。
基类:
// 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 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
。 因此,left
和right
指针均为空。
当然,以后可能会使用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()
中,您并不总是返回一个值:这可能会导致返回随机节点指针,从而导致内存损坏。 当您递归调用addNode(...)
时,您实际上应return (addNode(...))
) - 同样的错误在
Tree::min()
,Tree::max()
和Tree::findNode()
递归调用也是如此。 - 最后,如果 if 条件都不为真,即如果
thisKey
为 null),Tree::Successor()
不会返回 antything)。我在此函数的末尾添加了一个return thisKey;
。
只有在纠正了这些错误之后,我才能在没有段错误的情况下运行代码。 这里有一个bst.cpp和avl.cpp的连续摘录,在我不得不改变的行上加上感叹号的轿跑。
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 派生类销毁的最佳实践是什么
- 如何使用基类指针引用派生类成员
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 存储模板类型以强制转换回派生<T>
- 需要从 istream 和 ostream 派生 iostream
- 在 C++ 中用派生类型重写成员函数
- 具有多个类、派生类的C++正向声明
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 如果基类包含双指针成员,则派生类的构造函数
- 为什么此派生对象无法访问基类的后递减方法?
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践