c++PrimerPlus第13章

继承公有派生类:is-a 关系。

在使用公有派生类的时候必须明确是is-a关系。虽然该方法可以实现其他关系,但c++强调使用is-a关系。is-a是is a kind of 也就是派生类是基类的一种。
is-a的一种表现:基类的指针和引用可以访问派生类对象。

公有派生:派生类拥有基类的所有数据成员,以及部分方法。(构造函数,析构函数和赋值运算符重载函数不能继承)。

派生类不能访问基类的私有成员,但是可以通过共有成员进行访问。在派生类构造函数当中例外,私有成员可以被访问。

基类:

虚函数(最好使用)

使用virtual定义虚函数:虚函数使得通过基类的指针和引用访问方法时,根据对象的类型进行调用,而不根据指针和引用的类型。
在基类中定义了虚函数,则在派生类中可以不用定义。

联编

联编:将函数调用语句和函数定义的代码块连接在一起。

  1. 动态联编(晚期联编)
    和is-a的表示相关,对于基类的指针和引用的使用,需要在运行的时候才能将调用转换成代码(其所用的函数是不确定的)。如果指针和引用使用的方法没有多态则使用静态联编。
  2. 静态联编(早期联编)
访问控制

三种访问控制方法:public,private,protected:

  • 对于protected成员,在基类当中是私有的。在派生类当中可以被其他函数使用。通常不会用在数据成员(会破坏类隐藏数据的特性),通常用在方法上
    c++的创始人解释说:private比protected好,但是有的时候我们还要使用protected
  • private在派生类中不能使用。
析构函数

析构函数一定是虚函数

派生类

函数的特殊调用
  1. 在派生类中,如果构造函数没有显示的调用基类的构造函数,则自动调用基类的默认构造函数。
  2. 在派生类中,析构函数自动调用基类的析构函数。
  3. 在派生类中,默认复制构造函数会默认调用基类的复制构造函数和其含有对象对应的类的复制构造函数。(默认赋值运算符也一样)
构造函数

构造函数一定要调用基类的构造函数来实现基类的数据初始化。

  1. 对于可具体化的基类,需要定义两个构造函数。一个使用基类数据初始化,一个使用基类的对象初始化。
  2. 对于抽象基类:只需要使用数据初始化。
    构造函数当中:派生类的数据在前,基类在后。
多态
  1. 多态操作,一定要将基类对应函数设置成虚函数。
  2. 多态是替换,派生类中重定义的函数会将基类中名字相同的类全部替换。
  3. 多态操作,不要修改基类函数的参数类型个数和返回类型,对于所有的基类函数都要有对应的函数。
    又一个特例,就是对于返回值如果是基类,则可以修改成派生类,这种叫做返回类型协变。此时不会引发警告。
使用基类的方法

对于多态下的基类方法:可以使用作用域解析运算符在派生类中使用。

基类类型使用派生类
// 基类:base
// 派生类:baseplus
base a;
baseplus b;
base &c = b;
base *c = &b;
base c = b;  // 调用了复制构造函数

动态分配问题

  1. 对于基类来说,动态分配问题需要重写:复制构造函数,赋值运算符,析构函数。且三者十分相似。
  2. 对于派生类,其也需要重写三者,对于基类数据直接调用对应的函数。
    1. 复制构造函数:使用初始化列表调用基类复制构造函数
    2. 赋值运算符:使用作用域解析运算符调用基类赋值运算符
    3. 析构函数:默认调用就可以

抽象基类ABC

  1. 抽象基类中必须有纯虚函数。纯虚函数不需要有定义。
  2. 学院派认为:除了可以具体化的类,都应该定义成抽象基类。
  3. 纯虚函数需要在所有派生类中存在。

动态联编带来的代价

  1. 动态联编需要存储对象的类型。
  2. 虚函数带来的代价:
    1. 类需要创建虚函数表
    2. 对象需要存储vptr一个指向虚函数表的指针
    3. 调用虚函数的时候,需要查找虚函数表,找到对应的代码块。

你可能感兴趣的:(c++,开发语言,linux)