1、基类指针/引用不能指向protected与private的派生类对象:
例子:
//.h
class A{
...
};
class B: private A{
...
};
//.cpp
void func1(const A& a){...}
A a;
B b;
func1(a); // 成功,基类引用指向基类对象
func1(b); // 编译失败,私有继承下,基类引用无法指向派生类对象
原因:私有继承是has-a关系,基类所有成员变成了派生类私有成员,无法直接访问(继承实现,未继承接口),只能通过派生类成员函数访问。此时基类对象不可见,因此无法转换,编译器报错。
is-a:使用public继承,接口可见,基类派生类为同一类型对象,因此可以用基类指针引用指向派生类。
has-a:使用private继承,接口不可见,派生类包含基类对象,其只是实现上的技术(继承基类已经实现好的特性),在设计上没有意义。
2、尽量使用包含而不是private继承实现has-a关系:
即使包含比较复杂,但其可保证后续派生类不可更改基类函数。
复杂例子:
class A{
private:
class B:publuc C{
virtual func1(); //重写类C中函数func1,代替私有继承
};
B b;
...
};
代替如下代码
class A:private C{
virtual func1(); //重写类C中函数func1,私有继承
};
总结:
1、基类指针/引用不能指向protected与private的派生类对象。
2、尽量使用包含而不是private继承实现has-a关系。