C++之封装继承和多态

C++中很是重要的概念,尤为是相对于C语言而言,也是其具备如此高的工程使用性的重要缘由。编程

封装安全

所谓封装是将某些东西隐藏起来,让外界没法直接使用,而必须经过某些特定的方式才能访问。也便是,将抽象获得的数据和行为(相似于属性和方法)结合构成一个有机总体,将数据与操做数据的函数构成类,其中数据和函数都是类的成员。函数

其目的是将对象的使用者和设计者隔离开来,提升软件的可维护性和可修改性,使用者没必要了解具体的实现细节而只是经过外部接口及特定的访问权限使用类成员,从而加强了安全性且简化了编程,也使得不一样类之间的相互影响降到最低。优化

一个类的成员有三种访问权限能够选择spa

  • public        全部人都可访问
  • private    只有当前类中成员函数能够访问
  • protected  只有当前类中和当前类的派生类中的成员函数能够访问

若是没有显示声明,class中的成员数据或成员函数默认访问权限是private,struct中默认访问权限是public设计

继承指针

指的是新类从已有的类中获得已有的特性。调试

继承使得子类具备父类的某些数据和函数,而不须要再次编写相同的代码,在继承的同时,子类也能够从新定义某些数据和函数并覆盖父类原有的数据和函数。code

与类的成员访问权限相关,继承方式也分为三种:public,private,protected对象

通常分为单一继承和多重继承,经常使用的是单一继承,编程简单,可读性好。

须要注意的是class默认是private继承,而struct默认是public继承。

父类中的访问权限 继承方式 子类中的访问权限
public public public
private No access
protected protected
public private private
private No access
protected private
public protected protected
private No access
protected protected

子类会继承父类/基类除构造函数和析构函数之外的成员函数,通常析构函数定义为虚函数,不然的话析构时只会调用父类/基类中定义的析构函数而不会调用子类/派生类中的析构函数。

多态

父类成员函数前加virtual修饰就变成了虚函数。

纯虚函数就是父类只定义了虚函数而没有实现,则必须在子类中实现。若是子类中没有实现则子类仍为虚类,须要子类的子类去实现纯虚函数,即哪一层子类实现了纯虚函数,哪一层的子类才能够被初始化。纯虚函数至关于一个接口,子类必须实现这个接口才可使用。

而多态性就是为了接口重用,不管传递过来的是哪一个子类的对象,都能调用相应的子类函数。

多态是咱们能够用相同的方式处理不一样类型的对象,极大地提升了代码的可重复性。

多态性容许将子类类型的指针赋值给父类类型的指针,常经过虚函数来实现。虚函数就是容许子类从新定义的成员函数。

子类重写父类中的虚函数时,即便不用virtual声明,该函数也是虚函数,而父类中必需要有virtual声明。

一个接口,多种方法,多态主要有两种形式。

静态多态

在编译期将函数连接起来,此时便可肯定调用哪一个函数或模板,静态多态经过重载和模板实现。

在宏多态中,经过定义变量,编译时直接把变量替换,实现宏多态。

  • 优势
  1. 泛型编程,STL,很是便利
  2. 编译期完成,提升了运行效率
  3. 具备很强的适配性和松耦合性
  • 缺点
  1. 使得编程可读性下降,代码调试困难
  2. 没法实现木板的分离编译,工程量大时编译时间较长
  3. 没法处理异质对象集合

动态多态

在程序运行期间才能肯定调用哪一个函数或实现。父类指针或引用可以指向子类对象,调用子类的函数,因此在编译时没法肯定调用哪一个函数。

例如在父类中写一个虚函数,子类中进行重写,用一个指向父类的指针调用虚函数,实际上会调用在子类中重写的虚函数。

运行期多态的实现依赖于虚函数机制,当某个类声明了虚函数时,编译器将为该类对象安插一个虚函数表指针,并为该类设置一个惟一的虚函数表,表中存放该类虚函数的入口地址,运行期间经过虚函数表指针与虚函数表去肯定该类虚函数的真正实现。

  • 优势
  1. 面向对象设计中很是重要的特性,对客观世界直觉的认识。
  2. 能够处理同一继承体系下的异质类集合
    vector<Animal*> anims;
    Animal *anim1 = new Dog;
    Animal *anim2 = new Cat;
    
    // 处理异质类集合实例
    anims.push_back(anim1);
    anims.push_back(anim2);
  • 缺点
  1. 运行期间进行虚函数绑定,增长了程序运行开销
  2. 庞大的类继承层次,对接口的修改容易影响类的继承层次
  3. 虚函数在运行期绑定,编译器没法对其进行优化
相关文章
相关标签/搜索