栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C++虚基类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++虚基类

文章目录
  • 1、为什么要引入虚基类
  • 2、虚基类的概念
  • 3、虚基类的初始化
  • 4 关于虚基类子类构造函数
  • 5 虚基类构造函数调用顺序

1、为什么要引入虚基类

如果一个派生类是从多个基类派生出来的,而这些基类又有一个共同的基类,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性。

比如有以下结构

class  B{
  protected:  int a;
  public: B( ){ ...} };
class B1: public  B{
  public: base1( ){...} };
class B2: public  B{
  public: B2( ){...} }; 
class D:public B1,public B2{ . . .}



以下程序会报错,因为a具有二义性。

class B {
  protected:
   int a;
  public:
   B( ){ a=5; cout<<"B a="<B a=5
B1 a=15
B a=5
B2 a=25
B1 a=15
B2 a=25

能够看到a被初始化了两次,我们希望a只被再第一次初始化以后就不再继续初始化了。那么我们要使用虚基类。

2、虚基类的概念

如果将公共基类说明为虚基类。那么,对同一个虚基类的构造函数只调用一次,这样从不同的路径继承的虚基类的成员在内存中就只拥有一个拷贝。从而解决了以上的二义性问题。

继承方式

 class  派生类名:继承方式 virtual 基类名
 {   … }
 或
 class  派生类名: virtual 继承方式 基类名
 {  … }

我们将上面的继承结构改成如下所示

class B{
  protected:  int a;
  public: B( ){ ...} };
class B1: public virtual B{
  public: B1( ){...} };
class B2: public virtual B{
  public: B2( ){...} }; 
class D:public B1,public B2{ . . .}


3、虚基类的初始化

虚基类的初始化与一般的多重继承的初始化在语法上基本上是一样的,但有一些特殊的规定:
对同一个虚基类的构造函数只调用一次,且是在第一次出现时调用;

修改后代码

class B {
  protected:
   int a;
  public:
   B( ){ a=5; cout<<"B a="<B    a=5
B1   a=15
B2   a=35
D    a=35

可以看到a只被初始化了一次。

4 关于虚基类子类构造函数

如果在虚基类中定义有带形参的构造函数,并且没有定义默认形式的构造函数,则整个继承结构中,所有直接或间接的派生类都必须在构造函数的成员初始化表中列出对虚基类构造函数的调用,以初始化在虚基类中定义的数据成员。

class B {  int a;
  public:
   B(int sa)
  { a=sa;  cout<<"Constructing B"< 

任何一个类的上层(不一定是直接继承虚基类),只要含有虚基类都要再构造函数中调用虚基类的构造函数。

运行结果

Constructing B
Constructing B1
Constructing B2
Constructing D
5 虚基类构造函数调用顺序

若同一层次中同时包含虚基类和非虚基类,应先调用虚基类的构造函数,再调用非虚基类的构造函数,最后调用派生类构造函数;

 class X∶public Y,virtual public Z{
        //…
    };
    X  one;
    定义类X的对象one后,将产生如下的调用次序。
    Z( );
    Y( );
    X( );
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/821154.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号