如果虚基类中声明了非默认形式的构造函数,并且没有声明默认形式的构造函数,那么在整个继承关系中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化类表中列出对虚基类的初始化。
- #include <iostream>
- using namespace std;
- struct A1
- {
- A1(int i):ia1(i){} //A1(int i=0):ia1(i){}
- int ia1;
- void display(){cout <<"A1::display()"<<"..."<<ia1<<endl;}
- };
- struct B1 : virtual public A1
- {
- B1(int i):A1(i){} //B1(int i=0):A1(i){}
- int ib1;
- void display(){cout <<"B1::display()"<<endl;}
- };
- struct B2 : virtual public A1
- {
- B2(int i):A1(i){}
- int ib2;
- void display(){cout <<"B2::display()"<<endl;}
- };
- struct C1:public B1,public B2
- {
- C1(int i):B1(i),B2(i),A1(i){} //C1(int i1,int i2):B1(i1),B2(i2){}
- int ic1;
- void display()const {cout <<"C1::display()"<<endl;}
- };
- main()
- {
- C1 c1(1); //C1 c1(1,2);
- c1.A1::display();
- }
—————————————————————————————————————————————————————————————
#ifndef CHAP_11_H
#define CHAP_11_H
#include "iostream"
using namespace std;
class A
{
public:
A():iValue(100){}//如果虚基类中声明了非默认形式的构造函数,并且没有声明默认形式的构造函数,那么在整个继承关系中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化类表中列出对虚基类的初始化。
A(int i)
{
this->iValue=i;
}
int iValue;
};
class B:virtual public A
{
public:
void bPrintf()
{
cout<<"This is class B"<<endl;
}
};
class C:virtual public A
{
public:
void cPrintf()
{
cout<<"This is class C"<<endl;
}
};
class D:public B,public C
{
public:
D():A(10)
{
}
void dPrintf()
{
cout<<"This is class D"<<endl;
}
};
#endif
// chap_11.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "chap_11.h"
/****************************************/
// A
// B C
// D
//继承关系如上
//
//虚基类的构造函数
//前面讲过,为了初始化基类的子对象,派生类的构造函数要调用基类的构造函数。对于虚基类来讲,由于派生类的对象中只有一个虚基类子对象。
//为保证虚基类子对象只被初始化一次,这个虚基类构造函数必须只被调用一次。由于继承结构的层次可能很深,规定将在建立对象时所指定的类
//称为最派生类。C++规定,虚基类子对象是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的。如果一个派生类有一个直接或间接
//的虚基类,那么派生类的构造函数的成员初始列表中必须列出对虚基类构造函数的调用。如果未被列出,则表示使用该虚基类的缺省构造函数来
//初始化派生类对象中的虚基类子对象。
// 从虚基类直接或间接继承的派生类中的构造函数的成员初始化列表中都要列出这个虚基类构造函数 的调用。但是,只有用于建立对象的那个
//最派生类的构造函数调用虚基类的构造函数,而该派生类的基类中所列出的对这个虚基类的构造函数调用在执行中被忽略,这样便保证了对虚基
//类的对象只初始化一次。C++又规定,在一个成员初始化列表中出现对虚基类和非虚基类构造函数的调用,则虚基类的构造函数先于非虚基类的构
//造函数的执行。
/***************************************/
int _tmain(int argc, _TCHAR* argv[])
{
D d;
cout<<d.iValue<<endl; //错误,不明确的访问
cout<<d.A::iValue<<endl; //正确
cout<<d.B::iValue<<endl; //正确
cout<<d.C::iValue<<endl; //正确
B b;
cout<<b.iValue<<endl;
return 0;
}