《C++程序设计教程》——继承与多态

第3章 继承与多态

3.1 继承

3.1.1 继承的概念

注意:
1. 基类的构造函数和析构函数不可以被继承。
2. 派生类继承了基类的全部数据成员和除了构造、析构函数之外的所有成员函数。派生类对于基类成员的继承是没有选择的,不能选择接收或舍弃基类中的某些成员。
3. 派生类中除了与基类同名的成员外还可以添加新成员,用于实现新功能,保证派生类的功能在基类的基础上的发展。
4. 多个派生类可以继承自一个基类。
5. C++中可以通过派生形成类的层次结构,即一个基类可以是另一个更高层次类的派生类,而另一个派生类也可以继续产生派生类。

3.1.2 继承权限

这里写图片描述

3.1.3 派生类操作基类对象的四种方法

1.派生类对象可以向基类对象赋值。(单项的,不可逆)
2.派生类对象可以替代基类对象向基类对象的引用进行赋值或初始化。

ClassA obj_a;
ClassB obj_b;
ClassA &refa = obj_a;//可以将这一行改为 ClassA &refa = obj_b; 

3.如果函数的参数是基类对象或基类对象的引用,函数调用时的实参可以是派生类对象。

void func(ClassA &ref)
{
    cout<<ref.num<<endl;
}

在调用func()函数时可以用派生类ClassB的对象obj_b作实参:

func(obj_b);

4.派生类对象的地址可以赋值给基类指针变量。

3.2 派生类

3.2.1 构造函数

派生类中定义带参数构造函数的形式如下所示:

派生类名::派生类构造函数名(参数列表):基类构造函数名(基类构造函数参数表)
{
    派生类新增成员的初始化语句
}

3.2.2 析构函数

若派生类中没有显式的定义析构函数,编译系统会提供一个默认的析构函数。显式定义中,对象生命周期结束时会先调用派生类的析构函数,再调用基类的析构函数。

3.2.3 隐藏基类函数

派生类中重新定义基类同名函数的方法,称为对基类函数的覆盖或改写,覆盖后基类同名函数在派生类中被隐藏。定义派生类对象调用该函数时,调用的是自身的函数,基类同名函数不被调用。

3.3 多重继承

3.3.1 声明多重继承的方式

class 派生类名:继承方式 基类1名称,继承方式 基类2名称,...
{
    public:
        新增加的公有成员
    protected:
        新增加的保护成员
    private:
        新增加的私有成员
}

3.3.2 多重继承派生类的构造函数

定义:

派生类名::派生类构造函数名(参数总表):基类1构造函数名(参数表1),基类2构造函数名(参数表2),...
{
    派生类构造函数体
}

假如派生类是多重继承,并且新增数据成员有一个或多个对象成员,那么派生类需要初始化的数据有三部分:继承的数据成员、新增类的数据成员、新增普通成员。
这种复杂派生类定义:

派生类名::派生类构造函数名(参数总表):基类1构造函数名(参数表1),基类2构造函数名(参数表2),...子对象名1(参数表n),子对象名2(参数表n+1)
{
    派生类构造函数体
}

派生类构造函数调用顺序:
首先,调用基类构造函数。
其次,调用对象成员的构造函数。
最后,调用派生类的构造函数。

3.3.3 多重继承引起的二义性

  1. 调用不同基类中的同名成员时产生的二义性
    消除方法:
    (1)使用作用域限定符
    (2)派生类中定义与基类同名函数,将基类函数隐藏
  2. 派生类中访问公有成员时产生二义性

3.3.4 虚基类

在多重继承中,若一个类声明为虚基类,则能保证一个派生类间接地多次继承该类时,派生类中只继承该基类的一份成员,避免了派生类中访问公共基类公有属性多份拷贝的二义性。
定义:

class 派生类名:virtual 继承方式  基类名
{
    派生类成员
};

3.4 多态

3.4.1 多态性概念

3.4.2 虚函数

虚函数是运行时多态,若某个基类函数声明为虚函数,则其公有派生类将定义与其基类虚函数原型相同的函数,这时,当使用基类指针或基类引用操作派生类对象时,系统会自动用派生类中的同名函数代替基类虚函数。
声明形式:

class 类名
{
    virtual 函数返回值类型  函数名(参数表)
}
  1. 一般虚函数成员
    带有虚函数时,C++编译器的操作步骤:
    (1)为各个类建立虚函数列表,若无虚函数则不操作。
    (2)暂不连接虚函数,只是将各个虚函数地址放入虚函数表。
    (3)连接各静态函数。
  2. 虚析构函数

3.4.3 纯虚函数

在定义一个表示抽象概念的类时,有时无法或者不需要给出某些成员函数的具体实现,函数的实现在派生类中完成,基类中这样的函数声明为纯虚函数。
与虚函数相比,纯虚函数没有函数体,其作用是在基类中为派生类保留一个接口,方便派生类根据需要对它实现,实现多态。
声明形式:

virtual 函数返回值类型  函数名(参数表)= 0 ; 

3.5 抽象类与内部类

3.5.1 抽象类

如果一个类中至少包含一个纯虚函数,则该类成为抽象类,因此抽象类是基于纯虚函数的。
定义形式:

class 类名
{
    public:
    virtual 函数返回值类型  函数名(参数表)= 0;
    其他函数声明
}

3.5.2 内部类

class 外部类名
{
    外部类成员;
访问限定符:
    class 内部类名
    {
        内部类成员
    };
};

猜你喜欢

转载自blog.csdn.net/fengying2016/article/details/77527870
今日推荐