c++程序题,多重遗产继承办理出错求解

尽管大多数应用程序都使用单个基类的公用遗产继承办理但有些时候单遗产继承办理是不够用的,因为可能无法为问题域建模或对模型带来不必要的复杂性在这种情況下,多重遗产继承办理可以更直接地为应用程序建模

多重遗产继承办理是从多于一个直接基类派生类的能力,多重遗产继承办理的派苼类遗产继承办理其父类的属性

(1)与单遗产继承办理一样,只有在定义之后类才可以用作多重遗产继承办理的基类。

(2)对于类可鉯遗产继承办理的基类的数目没有语言强加的限制,但在一个给定派生列表中一个基类只能出现一次。

1、多重遗产继承办理的派生类從每个基类中遗产继承办理状态

对象ying_yang包含一个Bear子类对象、一个Endangered子类对象以及Panda类中声明的非static数据成员如下图所示:

2、派生类构造函数初始囮所有基类

派生类构造函数可以早构造函数初始化式中给零个或多个基类传递值。

构造函数初始化式只能控制用于初始化基类的值不能控制基类的构造次序。基类构造函数按照基类构造函数在类派生列表中的出现次序调用对于Panda,基类初始化次序是:

(2)Bear第一个直接基類。

(3)Endangered第二个直接基类,它本身没有基类

(4)Panda,初始化本身成员然后运行它的构造函数的函数体。

注意:构造函数调用次序既不受构造函数初始化列表中出现的基类的影响也不受基类在构造函数初始化列表中的出现次序的影响。例如:

这个构造函数将隐式调用Bear的默认构造函数尽管它不出现在构造函数初始化列表中,但仍然在Endangered类构造函数之前调用

单个基类情况下,派生类的指针或引用可自动转換为基类的指针或引用对于多重遗产继承办理,派生类的指针或引用可以转换为其任意基类的指针或引用

注意:在多重遗产继承办理凊况下,遇到二义性转换的可能性更大编译器不会试图根据派生类转换来区别基类间的转换,转换到每个基类都一样好例如:

通过Panda对潒调用print时,会导致一个编译时错误

1、基于指针或引用类型的查找

与单遗产继承办理一样,用基类的指针或引用只能访问基类中定义(或遺产继承办理)的成员不能访问派生类中引入的成员。当一个类派生于多个基类的时候那些基类之间没有隐含的关系,不允许使用一個基类的指针访问其他基类的成员例如:

2、确定使用哪个虚析构函数

我们假定所有根基类都将它们的析构函数定义为虚函数,那么通过丅面几种删除指针方法虚析构函数处理都是一致的。

假定上面四个指针都指向Panda对象则每种情况发生完全相同的析构函数调用次序,即與构造次序是逆序的:通过虚机制调用Panda析构函数再依次调用Endangered、Bear,ZooAnimal的析构函数

三、多重遗产继承办理派生类的复制控制

多重遗产继承办悝的派生类使用基类自己的复制构造函数、赋值操作符,析构函数隐式构造、赋值或撤销每个基类下面我们做几个小实验:

还是前面的類,只不过我将没有必要的虚函数去掉了下面我执行以下操作:

下面我们先来看TEST1的结果:

这个结果是毫无疑问的,先调用基类构造函数再调用派生类。

接着我们来看TEST2的结果:

首先调用默认构造函数构造一个zing_zing对象,然后调用拷贝构造函数将ying_ying拷贝至zing_zing。注意:这里用的是拷贝构造函数而不是赋值操作符,那什么时候用赋值操作符呢我们接着看TEST3的结果:

这种情况才调用赋值操作符:就是两个对象都已经汾配内存后,再进行赋值这里有个疑问,基类也定义了operator=了为什么不调用基类的operator=呢?我们将Panda类的operator=注释掉重新来做TEST3,好玩的结果出现了:

Panda的合成赋值操作符调用了两个基类的operator=

我们得出以下结论:如果派生类定义了自己的复制构造函数或赋值操作符,则负责复制(赋值)所有的基类子部分而不再调用基类相应函数。只有派生类使用合成版本的复制构造函数或赋值操作符才自动调用基类部分相应的函数。

最后我们来看一下析构函数的表现:

析构函数的行为是符合我们预期的这里有一点我没有体现出来就是zing_zing是ying_ying之后定义的对象,所以zing_zing的构慥函数先执行(前4行)后4行代表ying_ying构造函数的执行。如果具有多个基类的类定义了自己的析构函数则该析构函数只负责清除派生类。

四、多重遗产继承办理下的类作用域

在多重遗产继承办理下多个基类作用域可以包围派生类作用域。查找时同时检查所有基类遗产继承辦理子树,例如:并行查找Endangered和Bear/ ZooAnimal子树如果在多个子树上找到该名字,那个名字必须显式指定使用哪个基类否则,该名字的使用是二义性嘚

(1)Panda类的派生导致有两个名为print的成员是合法的。派生只是导致潜在的二义性如果没有Panda对象调用print,就可避免这个二义性你可以Bear::print或Endangered::print来調用。

(2)当然如果只在一个基类子树上找到声明是不会出错的。

下面仍然有个小实验要做:

我们的得出这样的结论:名字查找的过程昰这样的首先编译器找到一个匹配的声明(找到两个匹配的声明,这导致二义性)然后编译器才确定所找到的声明是否合法。

}

重复遗产继承办理是指一个派生類多次遗产继承办理同一个

基类C++中允许出现重复遗产继承办理。

解决遗产继承办理的重复问题有两种方法:

   —使用作用域分辨符来唯一標识并分别访问他们;

   —将直接基类的共同基类设置为虚基类

将直接基类的共同基类设置为虚基类

}

我要回帖

更多关于 遗产继承办理 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信