虚基类

如果虚基类中声明了非默认形式的构造函数,并且没有声明默认形式的构造函数,那么在整个继承关系中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化类表中列出对虚基类的初始化。

 

  1. #include <iostream>  
  2. using namespace std;  
  3. struct A1  
  4. {    
  5.     A1(int i):ia1(i){}             //A1(int i=0):ia1(i){}  
  6.      int ia1;  
  7.      void display(){cout <<"A1::display()"<<"..."<<ia1<<endl;}  
  8. };  
  9. struct B1 : virtual public A1  
  10. {  
  11.      B1(int i):A1(i){}    //B1(int i=0):A1(i){}  
  12.      int ib1;  
  13.      void display(){cout <<"B1::display()"<<endl;}  
  14. };  
  15. struct B2 : virtual public A1  
  16. {  
  17.     B2(int i):A1(i){}  
  18.     int ib2;  
  19.     void display(){cout <<"B2::display()"<<endl;}  
  20. };  
  21. struct C1:public B1,public B2  
  22. {  
  23.     C1(int i):B1(i),B2(i),A1(i){}    //C1(int i1,int i2):B1(i1),B2(i2){}   
  24.     int ic1;  
  25.     void display()const {cout <<"C1::display()"<<endl;}  
  26. };  
  27. main()  
  28. {  
  29.     C1 c1(1);            //C1 c1(1,2);  
  30.     c1.A1::display();  
  31. }  

—————————————————————————————————————————————————————————————

#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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值