C++ 面向对象 继承与派生

来源:互联网 发布:matlab分水岭算法 编辑:程序博客网 时间:2024/05/15 23:49
这部分实在是比较晦涩,带添加
看《Essential C++》看的比较累

继承
(1)公有继承(public)
公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,他们都保持原有的状态,而基类的私有成员仍然是私有的。

(2)私有继承(private)
私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并不能被这个派生类的子类所访问。

(3)保护继承(protected) 
保护继承的特点是基类的所有公有成员和保护成员都作为派生类的保护成员,并且只能被他的派生类成员函数或者友元访问,基类的私有成员仍然是私有的。

三种继承方式:
1.对于公有继承
(1)基类成员对其对象的可见性
公有成员可见,其他不可见。这可保护成员同于私有成员。
(2)基类成员对派生类的可见性
公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员。
(3)基类成员对派生类对象的可见性
公有成员可见,其他成员不可见。

2.对于私有继承
(1)基类成员对其对象的可见性
公有成员可见,其他不可见。
(2)基类成员对派生类的可见性
公有成员和保护成员可见,而私有成员不可见。
(3)基类成员对派生类对象的可见性
所有成员都是不可见的

3.对于保护继承方式
与私有继承相同。两者的区别在于对派生类的成员而言,对基类成员有不同的可见性。



派生类的构造函数和析构函数
1.构造函数
    派生类的对象的数据结构是由基类中说明数据成员和派生类中说明的数据成员共同构成的。将派生类的对象中由基类中说明的数据成员和操作所构成的封装体称为基类子对象,它由基类中的构造函数进行初始化。
    构造函数不能够被继承,因此,派生类的构造函数必须通过调用基类的构造函数来初始化基类子对象。所以,在定义派生类的构造函数时除了对自己的数据成员进行初始化外,还必须负责调用基类构造函数使基类的数据成员得以初始化。如果派生类中还有子对象时,还应包含对子对象初始化的构造函数。

派生类构造函数的调用顺序如下:
(1)基类的构造函数
(2)子对象的构造函数(如果有)
(3)派生类构造函数

2.析构函数
由于析构函数不能被继承,因此在执行派生类的析构函数时,基类的析构函数也会被调用。执行顺序是先执行派生类的析构函数,再执行基类析构函数,其顺序与执行构造函数时正好相反。


子类型化和类型适应
1.子类型化

2.类型适应

这里面的关键在于
a. 对类A的对象操作的函数,可以对类A的子类的对象进行操作,且子类型关系是不可逆的
b.类B是类A的子类型,可以将类B的对象赋值给类A对象,但是不能将类A对象赋值给类B对象
c.类B为类A的子类型,则操作类A对象的函数可以对类B对象操作


多继承
1.概念
多继承是指派生类有多个基类
class<派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,...

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

3.二义性问题
DAG图

4.虚基类
virtual<继承方式><基类名>
引入目的:消除二义性
引入虚基类后,派生类的对象中只存在一个虚基类的子对象。当一个类有虚基类时,编译器将为该类的对象定义一个指针成员,让它指向虚基类的子对象。该指针被称为虚基类指针。

虚基类的构造函数
    为了初始化基类的子对象,派生类的构造函数要调用基类的构造函数。对于虚基类来说,由于派生类的对象只有一个虚基类子对象。为了保证虚基类子对象只被初始化一次,这次虚基类构造函数必须只能被调用一次。由于继承的层次可能很深,规定将建立对象时所指定的类为最派生类。C++规定,虚基类子对象是由派生类的构造函数通过调用虚基类的构造函数进行初始化的。如果一个派生类有一个直接或者间接的虚基类,那么派生类的构造函数的成员初始化列表中必须列出对虚基类构造函数的调用,如果未被列出,则表示使用该虚基类的缺省构造函数来初始化派生类的虚基类子对象。
    从虚基类直接或者间接继承的派生类中的构造函数的成员初始化列表都要列出这个虚基类构造函数的调用。但是,只有用于建立对象的那个最派生类的构造函数调用虚基类的构造函数,而改派生类的基类中所列出的对这个虚基类的构造函数在执行中被忽略。这个便保证了虚基类的子对象只初始化一次。
    C++也规定,在一个成员初始化列表中出现对虚基类和非虚基类构造函数的调用,则虚基类的构造函数先于非虚基类的构造函数执行。

0 0
原创粉丝点击