第七章:继承与派生
主要内容:
1.类的继承与派生
2.类成员的访问控制
3.单继承与多继承
4.派生类的构造、析构函数
5.类成员的标识与访问
若为public继承方式:
1.派生类的成员函数可以直接访问基类的public和protected成员,不可访问基类的private成员。
2.派生类的对象只能访问基类的public成员
若为private继承方式:
1.派生类的成员函数可以直接访问基类的public和private成员,不能直接访问基类private成员。
2.派生类的对象不能直接访问基类中的任何成员。
若为protected继承方式:
1.派生类中的成员函数可以直接访问基类中的public和protected成员,不能直接访问private成员。
2.派生类的对象不能直接访问基类中的任何成员。
总结一下:
1.对于成员函数,就最近一层看到而言,可以访问public和protected属性的数据成员。
2.对于对象而言,只可以访问public属性的数据成员。
3.数据属性从基类到派生类开始看起,public=>protected=>private,属性的更改主要通过继承方式。
4.一定要看清楚,数据成员具体在那一层由public=>private/protected protected=>private 。这个影响派生类新成员函数是否可以访问基类数据成员。
基类与派生类对应关系:
1.单继承
2.多继承
3.多重派生
一个基类派生出多个不同的派生类
4.多层派生
派生类有作为基类,继续派生新的类
多继承派生类的声明:
class 派生类名:继承方式1 基类名1,继承方式2 基类名2,.....
{
成员声明;
}
继承时的构造函数:
1.基类的构造函数不被继承,派生类中需要声明自己的构造函数。
2.声明构造函数时,只需要对本类中新增的成员初始化,继承来的基类成员自动调用基类构造函数完成。
3.派生类的构造函数需要给基类的构造函数传递参数。
多继承的构造函数:
派生类名::派生类名(基类1形参,基类2形参,....基类n形参,本类形参):基类名1(参数),基类名2(形参),...基类名n(形参)
{
本类成员初始化赋值语句;
};
基类中声明有默认形式的构造函数或未声明构造函数时==》派生类构造函数可以不向基类构造函数传递参数
基类中未声明构造函数 ==》派生类中可以不声明,全采用缺省形式构造函数
基类中声明带有形参的构造函数==》派生类也要声明带形参的构造函数,然后将参数传递给基类构造函数
多继承且有内嵌对象时的构造函数
派生类名::派生类名(基类1形参,基类2形参,....基类n形参,本类形参):基类名1(参数),基类名2(参数),...基类名n(参数),对象数据成员的初始化
{
本类成员初始化赋值语句;
};
构造函数调用次序
1.基类构造函数,按照被继承时声明的顺序(由左到右)
2.成员对象的构造函数,按照类中声明的顺序
3.派生类的构造函数体中的内容
析构函数
1.析构函数同构造函数一样,也不被继承
2.析构函数调用次序与构造函数相反
二义性:
使用 虚函数技术和同名隐藏规则来解决
虚基类:
1.用于有共同基类的场合
2.作用:
2.1主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题
2.2为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝
3.声明:
以virtual 修饰说明基类
eg:class B1:virtual public B
eg:
class B{private:int b;};
class B1:virtual public B{private: int b1;};
class B2:virtual public B{private: int b2;};
class C : public B1,public B2{private:float d;}
下面的访问是正确的:
C cobj;
cobj.b;
虚基类及其派生类构造函数:
1.建立对象时所指定的类称为最(远)派生类。
2.虚基类的成员是由最派生类的构造函数通过调用虚基类的构造函数初始化的。
3.整个继承结构中,直接或间接继续虚基类的所有派生类,都必须在构造函数的成员初始化表中对虚基类的构造函数的调用。如果未列出那么就是会调用该虚基类的缺省构造函数。
4.建立对象时,只有最派生类的构造函数调用虚基类的构造函数,该派生类的其他基类对虚基类构造函数的调用被忽略。