C++虚基类解决二义性问题及执行结果分析

由于C++中允许多继承,所以会出现二义性问题:在多个派生类中,定义了相同名字的方法,这时再在main函数里面通过基类调用该方法时,编译器就犯难了。因为它不知道你到底是想用哪一个派生类里面的方法。

那么,现在又有了一个问题:假如有两个派生类DerivedA和DerivedB,它们的同名方法一个有参数,一个没有参数,是不是不会出现二义性问题了?

或者说,这两个派生类方法的一个是private,一个是public,是不是就可以防止二义性了呢?

答案是否定的。二义性的检查应在访问控制权限或者类型检查之前进行,因此访问控制权限不同或类型不同不能解决二义性问题。

既然上述提出的假设成立,那么应该怎样去有效的解决二义性问题呢?

虚基类就是为了这个解决这种二义性问题提出来的。

二义性产生的最主要原因是:基类在派生类中产生了两个子对象,从而导致了对基类成员访问的不唯一性。所以只需要使公共基类只产生一个子对象,就可以了。

也就是说,保证虚基类构造函数只被调用一次即可。虚基类自对象是由最派生类的构造函数通过调用虚基类的构造函数实现,此时,最派生类的所有基类中列出的对虚基类的构造函数的调用在执行过程中都将被忽略,而从保证对虚基类自对象值初始化一次。同时,最派生类的初始化列表必须列出对虚基类构造函数的调用;如果未列出,则表示使用该虚基类的默认构造函数。

(在继承结构的层次中,建立的对象属于这个结构中间的某个类,建立对象时所制定的类就是最派生类)

下面通过一个小例子分析一下:

#include <iostream>
using namespace std;
//基类
class Base
{
//公有成员
public:
 Base(char i)
 {
  cout << "Base's cons." << i<< endl;
 }
 ~Base()
 {
  cout << "Base's des." << endl;
 }
};
//派生类1
class Derivedl1:virtual public Base
{
//公有成员
public:
 Derivedl1(char i,char j):Base(i)
 {
  cout << "Derivedl1's cons." << j<< endl;
 }
 ~Derivedl1()
 {
  cout << "Derived's des." << endl;
 }
//私有成员
private:
 char b;
};
//派生类2
class Derivedl2:virtual public Base
{
//公有成员
public:
 Derivedl2(char i,char j):Base(i)
 {
  cout << "Derivedl2' cons." << j <<endl;
 }
 ~Derivedl2()
 {
  cout << "Derived12' des." << endl;
 }
};
//继承基类Base的派生类
class Derived2: public Derivedl1,public Derivedl2
{
//公有成员
public :
 Derived2(char i,char j,char k,char l,char m,char n)
  :Derivedl2(k,l),Derivedl1(i,j),Base(i),aa(m)
 {
  cout << "Derived2's cons." <<n << endl;
 }
 ~Derived2()
 {
  cout << "Derived2's des." << endl;
 }
//私有成员
private :
 Base aa;
};
//main函数
int main()
{
 Derived2 obj('a','b','c','d','e','f');
 return 0;
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/72a4696a195ea91d2a1687103191438f.html