根据我最喜欢的作家Scott Meyers 先生的说法,私有继承和组合意味着同样的事情,也就是 Has-A 关系。因此,可以从组合中获得的所有内容(包含,当类 A 具有类 B 作为其成员时)都可以通过私有继承获得,反之亦然。
所以下面的代码应该是一个Has-A关系,但在我看来,它不是!
class A : private boost::noncopyable {.. this is irrelevant };
谁能告诉我我失踪了?或者如何通过组合来实现这段代码?
根据我最喜欢的作家Scott Meyers 先生的说法,私有继承和组合意味着同样的事情,也就是 Has-A 关系。因此,可以从组合中获得的所有内容(包含,当类 A 具有类 B 作为其成员时)都可以通过私有继承获得,反之亦然。
所以下面的代码应该是一个Has-A关系,但在我看来,它不是!
class A : private boost::noncopyable {.. this is irrelevant };
谁能告诉我我失踪了?或者如何通过组合来实现这段代码?
你的例子可以通过这样的组合来实现:
class A {
private:
class B {
B(const B&) = delete;
B& operator=(const B&) = delete;
} b;
};
A
是不可复制的,因为它的成员b
是不可复制的。
您的示例仍然是 HAS-A 关系。
以下面的类为例,它大致相当于boost:noncopyable
:
class X {
private:
X(const X &);
X &operator=(const X &);
public:
X() {}
};
以下两个类具有相同的功能:
class A : private X {
public:
int a;
char b;
};
class B {
public:
int a;
char b;
X x;
};
在这个例子中,A
继承自X
whileB
包含一个X
. A
无法复制,因为它无法调用父级的复制构造函数,B
也无法复制,因为它无法调用其成员之一的复制构造函数。
A a1;
A a2(a1); // error
B b1;
B b2(b1); // error
boost::noncopyable
没有真正的语义意义,这只是一个禁止孙子的实现细节。
class A : private boost::noncopyable {};
A
没有, 因为是空的,无论是字面意思还是意义。 在这里,您会说“不可复制”,但我一般同意迈耶斯在一般情况下的观点。boost::noncopyable
boost::noncopyable
A
可以通过避免讨论特定示例的细节来回答这个问题。一个公开继承的类从定义其父级语义的所有内容开始——它的公共函数,以及它的公共状态变量(如果有的话)。如果这些都没有被覆盖,则它符合Liskov 替换原则,并且这是一个被广泛接受的设计原则,即应该以保持可替换性的方式覆盖这些属性。
对于私有继承,这些都不适用,除非程序员选择在派生类中实现(或重新实现)父类的所有公共属性,以保持可替换性。由于 C++ 不需要私有派生类来实现其父类的公共方法和变量的版本,因此这与派生类包含父类的实例并没有什么不同(除了代码中的微小和公式化更改)私人会员。特别是,对于私有继承,派生类在任何功能或操作方面都不是父类型的子类型,并且如果您的语言将派生类视为子类型,