c++ - 空对象模式、递归类和前向声明

标签 c++ recursion object null default

我有兴趣做类似下面的事情来遵守 Null 对象设计模式并避免大量的 NULL 测试:

class Node;
Node* NullNode;

class Node {
public:
  Node(Node *l=NullNode, Node *r=NullNode) : left(l), right(r) {};
private:
  Node *left, *right;
};

NullNode = new Node();

当然,正如所写,NullNode在Node类声明前后的内存位置是不同的。如果您不想使用默认参数(即删除 Node *r=NullNode),则可以在没有前向声明的情况下执行此操作。

另一种选择是使用一些继承:创建一个具有两个子类(NullNode 和 FullNode)的父类 (Node)。那么上面的节点示例将是 FullNode 的代码,上面代码中的 NullNode 将是继承自 Node 的 NullNode 类型。我讨厌通过诉诸继承来解决简单的问题。

因此,问题是:如何在 C++ 中将空对象模式应用于具有默认参数(它们是同一类的实例!)的递归数据结构(类)?

最佳答案

使用extern:

extern Node* NullNode;
...
Node* NullNode = new Node();

更好的是,让它成为静态成员:

class Node {
public:
  static Node* Null;
  Node(Node *l=Null, Node *r=Null) : left(l), right(r) {};
private:
  Node *left, *right;
};

Node* Node::Null = new Node();

也就是说,在现有代码和上述修改中,您泄漏了 Node 的一个实例。您可以使用 auto_ptr,但这会很危险,因为全局变量和静态变量的破坏顺序不确定(某些全局变量的析构函数可能需要 Node::Null,并且它可能或者到那时可能还没有消失)。

关于c++ - 空对象模式、递归类和前向声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1822143/

相关文章:

c++ - 从数字数组中查找可能的字母字符串数

php递归全局变量?

javascript - 对象化还是对象化?

c++ - 在 glPushMatrix 内部和外部实现 glulookat?

c++ - 删除表达式

c++ - 使目标文件符号成为可执行文件中的动态符号

list - 递归函数的惰性模式

java - 递归搜索二叉树

java - 在java中创建对象的最佳实践

ruby - 不同对象的实例变量都被改变