继承
类/结构可以具有继承关系。
如果类/ struct B
继承自类/ struct A
,这意味着 B
具有父 A
。我们说 B
是 A
的派生类/结构,A
是基类/结构。
struct A
{
public:
int p1;
protected:
int p2;
private:
int p3;
};
//Make B inherit publicly (default) from A
struct B : A
{
};
类/结构有 3 种形式的继承:
public
private
protected
请注意,默认继承与成员的默认可见性相同:public
(如果使用 struct
关键字)和 private
(class
关键字)。
甚至可能有一个 class
来自 struct
(反之亦然)。在这种情况下,默认继承由子控制,因此从 class
派生的 struct
将默认为公共继承,而从 struct
派生的 class
将默认具有私有继承。
public
继承:
struct B : public A // or just `struct B : A`
{
void foo()
{
p1 = 0; //well formed, p1 is public in B
p2 = 0; //well formed, p2 is protected in B
p3 = 0; //ill formed, p3 is private in A
}
};
B b;
b.p1 = 1; //well formed, p1 is public
b.p2 = 1; //ill formed, p2 is protected
b.p3 = 1; //ill formed, p3 is inaccessible
private
继承:
struct B : private A
{
void foo()
{
p1 = 0; //well formed, p1 is private in B
p2 = 0; //well formed, p2 is private in B
p3 = 0; //ill formed, p3 is private in A
}
};
B b;
b.p1 = 1; //ill formed, p1 is private
b.p2 = 1; //ill formed, p2 is private
b.p3 = 1; //ill formed, p3 is inaccessible
protected
继承:
struct B : protected A
{
void foo()
{
p1 = 0; //well formed, p1 is protected in B
p2 = 0; //well formed, p2 is protected in B
p3 = 0; //ill formed, p3 is private in A
}
};
B b;
b.p1 = 1; //ill formed, p1 is protected
b.p2 = 1; //ill formed, p2 is protected
b.p3 = 1; //ill formed, p3 is inaccessible
请注意,虽然允许 protected
继承,但实际使用它很少。如何在应用程序中使用 protected
继承的一个实例是部分基类专门化(通常称为受控多态)。
当 OOP 相对较新时,(公共)继承经常被称为模拟“IS-A”关系。也就是说,只有派生类的实例也是基类的实例时,公共继承才是正确的。
这后来被改进为 Liskov 替换原则 :只有当/在任何可能的情况下(并且仍然有意义)派生类的实例可以替换基类的实例时,才应该使用公共继承。
私人继承通常被认为体现了完全不同的关系:是根据实现的(有时称为“HAS-A”关系)。例如,Stack
类可以从 Vector
类私下继承。私有继承与聚合的相似性大于公共继承。
受保护的继承几乎从未使用过,并且对它所体现的关系类型没有普遍的一致意见。