c++中的代码复用

代码复用

面向对象编程的主要目的之一是提供可重用的代码。 -------- C++ Primer Plus

一、单继承

1、类继承的好处

  • 可以在已有类的基础上添加功能;
  • 可以给类添加数据;
  • 可以修改类方法的行为;

2、派生类和基类

2.1、派生类特征

  • 派生类对象中存储了基类的数据成员(派生类继承了基类的实现);
  • 派生类对象可以使用基类的方法(派生类继承了基类的接口);
  • 派生类需要自己的构造函数和析构函数;
  • 派生类可以根据需要添加自己的方法和数据成员;
  • 派生类不能直接访问基类的私有数据,而必须使用基类的公有方法才可以。派生类构造函数使用的是成员初始化列表,而其他成员函数使用的是另一种技术。

2.2、派生类的构造函数

​ 创建派生类对象时会先创建基类对象,所以在进入派生类构造函数之前需要创建基类对象,C++使用的是成员初始化列表。

2.3、派生类和基类的特殊关系

  1. 派生类对象可以使用基类对象;
  2. 基类指针可以在不进行显式类型转换的情况下指向派生类对象;
  3. 基类引用可以在不进行显式类型转换的情况下引用派生类对象;
  4. 可以将基类对象初始化为派生类对象,此时使用的是隐式复制构造函数;
  5. 可以将派生类对象赋值给基类对象,此时使用的是隐式赋值运算函数;

3、多态

3.1、公有继承(is - a)

​ 公有继承是最常用的继承方式,它建立一种 is - a 的关系,即派生类对象也是基类的一个对象,可以对基类执行的任何操作也可以对派生类执行。

3.2、多态公有继承

3.2.1、为什么使用多态

​ 希望派生类和基类中同一个方法(跟函数的重载不同)的行为不同,即方法的行为应该取决于该方法的对象。

3.2.2、实现机制
  1. 在派生类中重新定义基类的方法;
  2. 使用虚方法
    • 在方法声明前加virtual,即可将方法声明为虚方法;
    • 虚方法的作用是:如果方法是通过引用或指针而不是对象来调用的,他将决定使用哪一种方法。如果没有virtual,程序将根据引用或指针类型选择方法;若使用virtual,则根据引用或指针指向的对象类型来选择方法。
3.2.3、注意
  • 在派生类中使用基类方法的标准技术是使用作用域解析算符。
  • 经常在基类中将派生类会重新定义的方法声明为虚方法,方法在基类中被声明为虚后,它在派生类中将自动成为虚方法,可以加virtual
  • 虚析构函数;

4、抽象基类(Abstract base class)

4.1、为什么要用ABC

​ 两个类之间不是 is - a 的关系,直接继承不太理想;但二者之间又有一些共同的特征,分别定义效率不高;这时,我们可以将二者的共性抽离出来形成一个共同的基类,再分别派生。

4.2、机制

  • 纯虚函数(pure virtual function):再相应的函数声明后加 =0

4.3、说明

  • 为什么说这个共同的基类是抽象的:这个基类有派生类的共性,比如一个方法,但是派生类实现这个方法的方式可能不一样,因此,基类中的该方法不应有函数体,只是提供一个接口。
  • 要想成为抽象基类,必须包含纯虚函数;不能创建抽象基类的对象,但能创建引用和指针。

二、包含

1、包含(has - a)

  • 本身是另一个类的成员。

1.1、初始化

  • C++要求在构建对象的其他部分之前,先构建继承对象的所有成员对象。
  • 初始化的是成员对象,不是继承对象,所以初始化列表中使用的是成员名,而不是类名。

2、私有继承(has - a)

  • 使用私有继承,基类的公有成员和保护成员都将成为派生类的私有成员。
  • 语法和公有继承类似,功能和包含类似。

2.1、初始化

  • 使用初始化列表的方式来初始化继承对象,初始化列表使用的是类名。

2.2、注意

  1. 包含将对象作为一个命名的成员对象添加到类中,而私有继承将对象作为一个未被命名的继承对象添加到类中。
  2. 在私有继承中,未进行显式类型转换的派生类引用或指针,无法赋值给基类的引用或指针。

三、多重继承(MI)

  • MI描述的是有多个直接基类的类,与单继承一样,公有MI表示的也是 is - a 关系。

1、问题

  1. 从两个不同的基类继承同名的方法;
  2. 从两个或更多相关基类处继承同一个类的多个实例;

2、机制

  • 上述两个问题的根源是:派生类对象中有两个间接基类对象的拷贝,这不合理。
  • 引入虚基类;

3、虚基类

3.1、构造函数

  • C++在基类是虚时,禁止信息通过中间类自动传递给基类;编译器必须在构造派生对象之前构造基类对象组件;使用成员初始化列表来初始化。
  • 必须显式的调用间接基类的构造函数,否则会自动调用默认构造函数。

3.2、成员函数

  • 多重继承可能导致函数调用的二义性。
  • 可采用模块化编程的思想来解决这个问题。

3.3、支配

  • 使用虚基类将改变C++解析二义性的方式。使用非虚基类时,如果类从不同的类那里继承了两个或多个的同名成员时,则使用该成员名时,如果没有用类名进行限制,将导致二义性。但如果使用的的虚基类,则不一定会导致二义性。
  • 如果某个名称优先于(dominates)其他所有名称,则使用它时,即使不使用限定符,也不会导致二义性。
  • 支配:派生类中的名称优先于直接或间接祖先类中相同的名称;
  • 虚二义性规则(支配规则)和访问规则无关。

原文链接: https://www.cnblogs.com/xxiaobai/p/12659473.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    c++中的代码复用

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/195553

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午7:00
下一篇 2023年2月12日 下午7:01

相关推荐