让我们试试你的实现:
#include <iostream>
class BinaryTree {
public:
BinaryTree(int value, BinaryTree * left, BinaryTree * right) : value_(value), left_(left), right_(right) {}
void printBinaryTree(int depth = 0) {
for ( int i = 0; i < depth; i++ ) std::cout << " ";
if ( this == NULL ) {
std::cout << "Null node, returning..." << std::endl;
return;
}
else {
std::cout << value_ << std::endl;
}
left_->printBinaryTree(depth+1);
right_->printBinaryTree(depth+1);
}
private:
int value_;
BinaryTree * left_;
BinaryTree * right_;
};
int main() {
BinaryTree leaf(0,NULL,NULL);
BinaryTree top(1,&leaf, &leaf);
top.printBinaryTree();
return 0;
}
如果我们进行这个运行,我们会得到如下所示的输出:
1
0
Null node, returning...
Null node, returning...
0
Null node, returning...
Null node, returning...
这里解释了这个工作的原因:Accessing class members on a NULL pointer
但是,根据 C++ 标准,这样做是未定义的行为。就像,这只是因为你的,或者在这种情况下我的,编译器的实现能够使这个工作。这不是任何形式的保证,这会降低您的可移植性,如果您需要更新编译器,甚至可能会停止工作!
有很多替代方案。您已经列出了一些,但我必须说我不喜欢静态实现,因为从设计的角度来看它并没有真正的意义,并且会使您的所有代码变得一团糟。另一个解决方案是使printBinaryTree
函数成为虚拟函数,并将叶节点定义为树的子类。这是一个例子:
#include <iostream>
class BinaryTree {
public:
BinaryTree(int value, BinaryTree * left, BinaryTree * right) : value_(value), left_(left), right_(right) {}
virtual void printBinaryTree(int depth = 0) {
for ( int i = 0; i < depth; i++ ) std::cout << " ";
std::cout << value_ << std::endl;
left_->printBinaryTree(depth+1);
right_->printBinaryTree(depth+1);
}
int getValue() { return value_; }
private:
int value_;
BinaryTree * left_;
BinaryTree * right_;
};
class BinaryTreeLeaf : public BinaryTree {
public:
BinaryTreeLeaf(int value) : BinaryTree(value, NULL, NULL) {}
virtual void printBinaryTree(int depth=0) {
for ( int i = 0; i < depth; i++ ) std::cout << " ";
std::cout << getValue() << std::endl;
}
};
int main() {
BinaryTreeLeaf leaf(0);
BinaryTree top(1,&leaf, &leaf);
top.printBinaryTree();
return 0;
}
根据需要,此处的输出是:
1
0
0