C++学习(4)——继承中的二义性问题和虚基类

#include<iostream>
#include<stdio.h>
using namespace std;
/************************************************************************
* 二义性问题
************************************************************************/
//基类
class CBase
{
    int a;
public:
    int x;
    void func();
};

//派生类1
class CDerive1:public CBase //可以添加virtual虚基类
{
    int b;
public:
    int y;
    void func1();
};

//派生类2
class CDerive2:public CBase//可以添加virtual虚基类
{
    int c;
public:
    int z;
    void func2();
};

//子派生类
class CDerive12:CDerive1,CDerive2
{
    int d;
public:
    int yz;
    int func12()
    {
        //x=10;    //error C2385: 'CDerived12::x' is ambiguous
        //func();    //error C2385: 'CDerived12::func' is ambiguous
        CDerive1::x=10;    
        CDerive1::func();    
        return 0;
    }
};

int main()
{
    CDerive12 obj;
    return 0;
}
解决二义性问题的方法:
1.利用范围运算符指明所要调用的成员的类属范围;
2.在派生类中重新定义一个与基类中同名的成员,使该成员隐蔽基类的同名成员;
3.将公共基类说明为虚基类,避免在派生类中保留多个基类的备份,而只保存一个实例
 

### C++虚基类继承的概念及用法 #### 虚基类的概念与作用 在C++中,虚基类是一种特殊的继承方式,用于解决多重继承带来的二义性重复数据成员的问题。当一个派生类从多个基类派生而来,而这些基类又共同继承同一个祖先类时,可能会导致该祖先类被多次实例化的情况。这种现象被称为“菱形继承问题”。为了避免这种情况的发生,C++提供了虚继承机制[^1]。 通过使用`virtual`关键字修饰继承关系,可以让所有间接派生的子类共享同一份基类实例,从而消除冗余的数据成员并简化程序逻辑[^3]。 #### 虚继承的应用场景 虚继承主要应用于复杂的类层次结构中,特别是涉及多重继承的情况下。例如,在设计图形界面库或者游戏引擎等大型软件项目时,经常会出现这样的需求——某些功能模块可能需要同时具备多种行为特征(即它们是从同父类派生出来的),但又要确保会因为过度复制而导致资源浪费或操作混乱[^2]。 下面是一个典型的例子: ```cpp class Base { public: int baseValue; }; // 定义两个中间层类,并都采用虚拟方式继承自Base class DerivedA : virtual public Base {}; class DerivedB : virtual public Base {}; // 终极派生类同时继承于DerivedADerivedB class FinalClass : public DerivedA, public DerivedB {}; int main(){ FinalClass obj; // 管FinalClass如何组合其直接父母节点, // 都只会保留唯一的一份来自Base的基础属性。 obj.baseValue = 42; cout << "The value is: " << obj.baseValue << endl; return 0; } ``` 在这个示例里,无论 `FinalClass` 是怎样由 `DerivedA` `DerivedB` 构建起来的,它最终都会维持单一版本的 `baseValue` 成员变量。 #### 实现细节分析 需要注意的是,虽然表面上看似乎只是简单加了个关键词而已,但实际上编译器背后做了很多额外工作来支持这一特性。比如调整构造顺序、增加指向虚表(vtable) 的指针等等。因此相较于普通的单向线性继承而言,性能开销会稍大一点;过考虑到现代计算机硬件的能力以及由此获得的好处,这点代价通常是值得接受的[^4]。 另外值得注意的一个地方在于初始化列表上:对于虚基类来说,即使某个特定路径上的某级子类别已经对其进行了设定,最末端的实际创建实体仍然负有责任去显式指定参数给定值。这是因为只有后者才知道确切的需求是什么样的。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值