首页 > 其他分享 >虚继承

虚继承

时间:2023-03-27 20:19:03浏览次数:28  
标签:setA 继承 void public int class

多继承产生的冲突

当存在多基类时,看下面这个例子:

class A
{
protected:
    int a;
};
class B : public A
{
protected:
    int b;
};
class C : public A
{
protected:
    int c;
};
class D : public B, public C
{
public:
    void setA(int a) {this->a = a;}
    void setB(int b) {this->b = b;}
    void setC(int c) {this->c = c;}
};
int main()
{
    D d;
}

编译会报错:

error: non-static member 'a' found in multiple base-class subobjects of type 'A':
    class D -> class B -> class A
    class D -> class C -> class A

编译器不知道成员变量a是来自B 还是来自C。

这是一个菱形继承的问题:

 

为了消除这个问题,我们可以用的一个方法是在变量面前指定具体哪个类。

void setA(int a) {this->B::a = a;}

int main()
{
    D d;
    d.setA(9);
    std::cout << d.B::a << std::endl; // 输出:9
}

当存在这种菱形继承的时候,类D拥有两套类A的成员数据,虽然可以通过添加限定符进行独立访问,但是也同样存储了两份数据占用了两份空间

可以查看内存空间:

 

使用虚继承可以解决菱形继承问题。

 

虚继承

虚继承 是面向对象编程中的一种技术,是指一个指定的基类,在继承体系结构中,将其成员数据实例共享给也从这个基类型直接或间接派生的其它类。

我们做出修改使类B 和类C 虚继承自类A:

class A
{
public:
    int a;
};

class B : public virtual A
{
public:
    int b;
};

class C : public virtual A
{
public:
    int c;
};

class D : public B, public C
{
public:
    void setA(int a) { this->a = a; }
    void setB(int b) { this->b = b; }
    void setC(int c) { this->c = c; }
};

int main()
{
    D d;
    d.setA(9);
    std::cout << d.a << std::endl;
}

我们看一下内存结构:

可以看出,实际上类D 只保留了一份类A的数据成员a。此时,类A就被成为虚基类,用来解决菱形继承带来的命名冲突和数据冗余问题。

 

标签:setA,继承,void,public,int,class
From: https://www.cnblogs.com/errorman/p/17262662.html

相关文章

  • 继承与派生
    目录继承介绍继承与抽象总结属性查找单继承下的属性查找多继承下的属性查找非菱形查找深度优先广度优先super关键字与mro列表派生方法案例mro列表组合继承介绍继承是一种......
  • CSS06.继承
    继承子元素会继承父元素的某些(不是全部)CSS属性通常,跟文字内容相关的属性都能被继承例:background-color、weigh、height不能被继承概念:子标签会继承父标签的某些......
  • JS基础 原型与继承
    阅读目录原型基础原型对象使用数组原型对象的concat方法完成连接操作默认情况下创建的对象都有原型。以下x、y的原型都为元对象Object,即JS中的根对象创建一个极简对象(......
  • 25.封装、继承、多态
    封装、继承、多态一、封装1.高内聚,低耦合高内聚就是类的内部数据操作细节自己完成,不允许外部干涉。低耦合就是仅暴露少量的方法给外部使用。2.数据的隐藏通常,应禁止......
  • 1. 继承的学习和使用
    继承的学习和使用继承概述继承是面向对象三大特性之一(封装,继承,多态)继承使子类拥有父类的属性和方法,并且可以定义自己独有的属性和方法继承的格式关键字:exte......
  • 继承
    封装:可以想象成遥控器,你不需要知道它内部怎么实现的,它封装好你拿来就能用就行了继承:把这几个类重复的成员单独拿出来封装成一个类,作为它们几个共同的父类继承的特性:单根......
  • 继承基本概念
    是一种代码复用机制,通过继承,一个类(称为派生类或子类)可以继承另一个类(称为基类或父类)的属性和行为。子类继承父类的成员变量、成员函数、构造函数和析构函数等,并且可以在此......
  • C++温故补缺(七):;类的访问控制和继承
    类的访问控制和继承类的静态成员类的静态成员用关键字static修饰,类似静态变量或静态函数,也是有共享的概念类的静态变量:静态变量在类的所有对象中共享,不能再类的定......
  • Java基础知识点(继承中构造方法的的访问特点
    一:概述​1.父类的构造方法不会被子类继承。2.子类中的构造方法默认先访问父类中的无参构造,在执行自己。换句话来说,子类不能得到父类的的构造方法,子类进行构造方法默认先访问......
  • Python基础:面向对象-继承和多态
    一、继承Python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性的方法。作用:可以减少代码重复,提升代码复用率。简单示例如下:#父类AclassAni......