private继承
- 如果class之间的继承关系是private,那么编译器不会自动将一个子类对象转换为父类对象。
- 使用private继承的所有父类成员,在子类中都是private类型的,即使成员在父类中是public或者protected的。
- private意味着只有实现部分被继承,接口部分应略去。
- private继承可以造成empty base最优化,如下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Empty{};
class A{
private:
int x;
Empty e;
};
cout << sizeof(A);//8
cout << sizeof(int);//4
```
使用私有继承可以避免
```cpp
class A : private Empty{
int x;
}
cout << sizeof(A);//4
cout << sizeof(int);//4
多重继承
多重继承中的歧义
看下面的代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class A{
public:
void f1();
};
class B{
public:
void f1();
};
class Derived:
public A,
public B{
};
Derived d;
d.f1(); //ambiguous! A::f1() or B::f1()在基类中定义命名相同的函数很容易造成这种问题,即使继承方式可能是私有或者方法名是私有,都会造成歧义。可以使用作用域+函数的方式显示声明要调用的函数,如A::f1();
菱形继承
1 | class File{ |
- 这是一个典型的菱形继承,假设File类有个成员变量Filename,那么IOFile内有多少个Filename呢?有两种说法。
IOFile从InputFile和OutputFile均复制了一份,存在两份filename。
IOFile只应该有一份。
c++默认的做法是第一种,产生两个filename成员。 - 解决方式是virtual继承,也就是说File类必须是virtual base class
1 | class File{ |
这样在IOFile内部就只有一份filename副本。
那么虚继承是怎么实现这个功能的呢。具体在虚继承内存布局章节会讨论。