我有兴趣做类似下面的事情来遵守 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/