C++基础知识: 公有继承,保护继承,私有继承的总结,私有继承的用意何在

来源:互联网 发布:什么软件挣钱快好提现 编辑:程序博客网 时间:2024/05/20 18:45


今天被问到C++中私有继承的作用是什么?第一反应是关于访问权限的改变,基类被子类私有继承后,基类中即使是共有public,保护protected的成员变量或者成员函数都会在子类中变为私有成员和私有成员变量,子类的派生类或者子类的对象再也无法访问这些成员和成员变量。


其实,这个回答只答出了最为基本的概念,那就是私有继承对访问权限的改变。 但是,更为深处的理解是,既然私有继承这么小众化,为什么我们还要使用私有继承?


回答之前,再来复习一下public,protected,private的作用


作用域

1.  类的一个特征就是封装, pubic 和 private 作用就是实现这一目的

Public:  可以被该类中的函数,子类的函数,友元函数访问,也可以由该类的对象访问


Protected: 可以被该类中的函数,子类的函数,友元函数访问, 但不可以被该类的对象访问(类外)


Private: 只能被该类中的函数,友元函数访问, 不可以被子类的函数访问,也不可以被该类的对象访问


附上例子说明:

#include<iostream>#include<assert.h>using namespace std;class A{public:  int a;  A(){    a1 = 1;    a2 = 2;    a3 = 3;    a = 4;  }  void fun()  {    cout << a << endl;    //正确    cout << a1 << endl;   //正确    cout << a2 << endl;   //正确,类内访问    cout << a3 << endl;   //正确,类内访问  }public:  int a1;  void publicfun(){}protected:  int a2;  void protectedfun(){}private:  int a3;  void privatefun(){}};int main(){  A itema;  itema.a = 10;    //正确  itema.a1 = 20;    //正确  itema.publicfun(); // 正确  itema.a2 = 30;    //错误,类外不能访问protected成员  itema.protectedfun(); //错误,类外不能访问protected成员函数  itema.a3 = 40;    //错误,类外不能访问private成员  itema.privatefun(); //错误,类外不能访问private成员函数  system("pause");  return 0;}

继承中的特点:


1. public 继承: 父类public,protected, private成员或者成员函数的访问属性在子类中变为public,protected, private, 这是一个典型的 “接口” 继承

2. protecte的继承: 父类public,protected, private成员或者成员函数的访问属性在子类中变为protected,protected, private, 这是一个“实现”继承

3. private继承:  父类public,protected, private成员或者成员函数的访问属性在子类中变为private,private, private, 这也是一种“实现”继承


但无论那种继承方式,上面两点没有变化:

1 private 成员只能被本类(友元)访问,不能被派生类访问,也不能被类对象访问

2 protected成员可以被派生类访问, 不能被类对象访问


现在讲讲 私有继承的意义: 


私有继承的含义:私有继承意味着 "用...来实现"
如果使类D私有继承于类B,这样做是因为你想利用类B中已经存在的某些代码,而不是因为类型B的对象和类型D的对象之间有什么概念上的关系
因而,私有继承纯粹是一种实现技术。

私有继承意味着只是继承实现,接口会被忽略。如果D私有继承于B,就是说D对象在实现中用到了B对象,仅此而已
私有继承在软件 "设计" 过程中毫无意义,只是在软件 "实现" 时才有用。


以下节选自http://blog.chinaunix.net/uid-20235103-id-1970688.html

看完之后花时间理解了一下,发现确实豁然慨然,私有继承绝不仅仅是在访问权限上的考虑,再往深层次考虑,就会发现,和 组合 设计模式相比较,私有继承也是一种 has a 的实现,两个类之间不再是 is a的关系,所以私有继承情况下,编译器不会为了使 函数调用成功而需要将子类隐式转换为父类。 


附上案例

class B {};class D: public class B{};class E: private classB{};void eat(B& b);int maint(int arg, char** argc){B b;D d;E e;eat (b) ;  // correct, eat(d); // also correct, since D "is a " of B, public inhertance is an interface inheratance, compiler will static-cast it for success of compilationeat(e);  // NOT correct, e private inherits B, e is not "is a" of B, only indicate e "has a" of B, compiler won't static cast it for compilation success}


  private inheritance(私有继承)更可能在以下情况中成为一种设计策略,当你要处理的两个 classes(类)不具有 is-a(是一个)的关系,而且其中的一个还需要访问另一个的 protected members(保护成员)或需要重定义一个或更多个它的 virtual functions(虚拟函数)。甚至在这种情况下,我们也看到 public inheritance 和 containment 的混合使用通常也能产生你想要的行为,虽然有更大的设计复杂度。谨慎使用 private inheritance(私有继承)意味着在使用它的时候,已经考虑过所有的可选方案,只有它才是你的软件中明确表示两个 classes(类)之间关系的最佳方法。

  Things to Remember


 
 ·private inheritance(私有继承)意味着 is-implemented-in-terms of(是根据……实现的)。它通常比 composition(复合)更低级,但当一个 derived class(派生类)需要访问 protected base class members(保护基类成员)或需要重定义 inherited virtual functions(继承来的虚拟函数)时它就是合理的。

  ·与 composition(复合)不同,private inheritance(私有继承)能使 empty base optimization(空基优化)有效。这对于致力于最小化 object sizes(对象大小)的库开发者来说可能是很重要的。






0 0