C++ 私有继承
私有继承
私有继承是一种不同的方法,我们可以在其中实现has-a关系。通过私有继承,我们可以将基类的保护成员和公有成员转换为派生类的私有成员。这意味着在实现了私有成员类之后,所有成员类的基类都变成了私有类。然而,我们可以在派生类的成员函数中实现这些私有类。
让我们通过一个程序简要了解私有继承。
class Person {};
class Student:private Person {}; // private
void eat(const Person& p){} // anyone can eat
void study(const Student& s){} // only students study
int main()
{
Person p; // p is a Person
Student s; // s is a Student
eat(p); // fine, p is a Person
eat(s); // error! s isn't a Person
return 0;
}
在上述程序中,在公有继承中,如果两个类之间的关系被设置为私有类,则编译器无法将派生类转换为基类。这就是为什么对象S无法调用函数eat()。 在公有继承的情况下,基类的公有方法成为派生类的公有方法。换句话说,我们可以说派生类通过继承来继承基类的属性。这是一种IS-A关系的类型。但是在私有继承的情况下,基类的公有方法变为派生类的私有方法,即使基类是受保护或公有的。在这种情况下,派生类不继承基类的属性。 但是在私有继承的情况下,我们应该非常小心。私有继承非常令人困惑。这里的继承并不意味着拥有。假设父类将特殊糖果的秘密配方交给孩子,并要求孩子保守这个秘密。孩子可以给人们不同种类的糖果,但不能分享糖果的配方。通过私有继承,派生类可以由基类实现,但不是由基类拥有。因此,派生类不向外界展示其接口。唯一向外界展示的是产品。 通过私有继承,一个类可以通过实现被继承。类声明可以被用户直接访问,用户是接口一部分。用户还可以通过类声明间接访问实现类。 示例:
#include
using namespace std;
class Engine
{
public:
Engine(int nc){
cylinder = nc;
}
void start() {
cout << getCylinder() <<" cylinder engine started" << endl;
};
int getCylinder() {
return cylinder;
}
private:
int cylinder;
};
class Car : private Engine
{ // Car has-a Engine
public:
Car(int nc = 4) : Engine(nc) { }
void start() {
cout << "car with " << Engine::getCylinder() <<
"cylinder engine started" << endl;
Engine:: start();
}
};
int main( )
{
Car c(8);
c.start();
return 0;
}
输出:
解释:
从示例中我们可以看到,Car类继承了一个Engine组件,比如一个cylinder。Car方法可以在内部使用Engine方法getCylinder()来访问Engine组件cylinder。
结论
- 当你处理两个不相关的类,其中一个需要访问另一个的保护成员或需要重新定义一个或多个虚函数时,私有继承很可能是一种合理的设计策略。
- 私有继承意味着“是由…实现的”。通常比组合差。
- 如果你让类D从类B私有继承,那是因为你有兴趣利用类B中可用的一些特性,而不是因为类型B和D之间有任何概念上的关系。
- 私有继承在软件设计期间无意义,只有在软件实现期间才有意义。