虚拟继承下 Virtual Function 的语意

考虑下面的 virtual base class 派生体系:

class Point2d
{
public:
    Point2d(float = 0.0, float = 0.0);
    virtual ~Point2d();

    virtual void Mumble();
    virtual float Z();
    //...
protected:
    float _x, _y;
};

class Point3d:public virtual Point2d
{
public:
    Point3d(float = 0.0, float = 0.0, float = 0.0);
    ~Point3d();

    float Z();
protected:
    float _z;
};

虽然 Point3d 有唯一的(同时也是最左边的) base class, 也就是 Point2d, 但 Point3d 和 Point2d 的起始部分并不像非虚拟的单一继承情况那样一致, 这种情况具体如下图, 由于 point2d 和 Point3d 的对象不再相符, 两者之间的转换也就需要调整 this 指针, 至于在虚拟继承的情况下要消除 thunks, 一般而言,已经被证明是一项高难度技术.

当一个 virtual base class 从另一个 virtual base class 派生而来, 并且两者都支持 virtual functions 和 nonstatic data members 时, 编译器对于 virtual base class 的支持简直像是进了迷宫. 所以只需记住: 不要在一个 virtual base class 中声明 nonstatic data members , 如果这么做, 你会距离复杂的深渊越来越近, 终不可拔.

时间: 2024-10-13 14:02:56

虚拟继承下 Virtual Function 的语意的相关文章

多重继承下 Virtual Function 的语意

在多重继承中支持 virtual function, 其复杂度围绕在第二个及后继的 base classes 上, 以及必须在执行期调整 this 指针这一点, 以以下的 class 体系为例: class Base1 { public: Base1(); virtual ~Base1(); virtual void SpeakClearly(); virtual Base1* Clone() const; protected: float data_base1; }; class Base2

C++ 继承、多继承、虚拟继承对象模型

C++面向对象语言一大难点是继承,但又是不得不掌握的.简单的继承是很容易理解的,但是当涉及到多继承,设计到虚函数的继承,特别是涉及到虚继承时,问题就会变得复杂.下面的内容来自参考资料中的三篇文章.C++的继承学习中,最主要是要掌握派生类的对象模型,基类和派生类指针之间的向上向下类型转换,当继承中的出现虚函数成员函数的访问(多态),虚继承是如何通过引入虚基表解决"菱形继承"中存在多份公共基类的问题. 一.简单的对象模型 1.定义 class MyClass { public: int v

深入探索C++对象象模型--拷贝构造函数 &&多重继承 虚拟继承 内存分布

拷贝构造函数 如果没有定义拷贝构造函数,那么编译器会自动生成一个拷贝构造函数,但是这个拷贝构造函数是有一定限度的. 一般来说这个拷贝构造函数是按照位直接拷贝的,但是在有些情况下这种初始化是有问题的,在特殊的四种情况下是有问题的,在有问题的情况下,可以举例说明. 如果一个有多态性质的对象,子类赋值给父类,调用了拷贝构造函数,这个时候就需要给父类的虚拟函数表重新分配,使得虚拟函数表和子类不是同一个,这样bitwist就不能有效 对于在函数参数中调用拷贝构造函数,参数是实参的一根拷贝,对于函数的返回值

虚拟继承C++

C++中虚拟继承的概念 为了解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类.这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射.这样不仅就解决了二义性问题,也节省了内存,避免了数据不一致的问题.class 派生类名:virtual 继承方式 基类名virtual是关键字,声明该基类为派生类的虚基类.在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用.声明了虚基类之后,虚基类

菱形的虚拟继承

问题引入: 如果有Base类,B1类,B2类,D类,如下图继承关系 那么按一般的继承来看,D类创造的对象会继承B1类的方法与成员,同时也会继承B2类的方法与成员: 接下来类B1 , B2 会分别去继承Base类的方法与成员,那么D类的对象在调用Base类的方法时,到底是继承B1类这边的Base,还是会继承B2类这边的Base,此时就会产生二义性 为了解决这个问题,就看看虚拟继承是怎么来解决这个二义性问题的 菱形的虚拟继承的源代码 #include <iostream> using namesp

菱形虚拟继承&虚函数表&对象模型

菱形继承: Assitant的菱形继承对象模型 Assitant中有两份Person成员,存在二义性和数据冗余. 所以我们引出了虚拟继承. virtual虚继.不会在子类中创建父类成员,但是子类中可以引用,就像指针一样.主要用在菱形继承,也叫钻石继承. 虚拟继承对象模型 class Student : vitrual public Person class Teacher : virtual public Peraon 虚函数表 通过一块连续内存来存储虚函数的地址.这张表解决了继承.虚函数(重写

C++ 实用泛型编程之 虚拟函数(C++ virtual function)杂谈

一 C++虚拟函数(C++ virtual function)杂谈 我们在编程的时候,经常会遇到这样的情况,假设有两个对象,你要在函数中分别调用它们的OnDraw方法,我们以前的做法一般是这样的. void f(int iType) { switch(iType) { case 1: //CCircle OnDraw break; case 2: //CRectangle OnDraw break; } } 这种方法当然能解决我们的问题,但是如果有新的类型要增加,它就必须要往下加代码才行了,这样

虚函数和虚拟继承的内存分布

一.虚函数 (1)C++中的虚函数的主要作用:实现了多态的机制. (2)多态:用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态",这是一种泛型技术.所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法.比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议. (3)多态要基于函数重载,所以如果子类没有重载父类的虚函数那是一件毫无意义的事情. 二.虚函数表 1.虚函数表:虚函数表C+

含有虚函数菱形的虚拟继承(没有对虚函数进行重写)

在VS2013编程,调试 问题 :  菱形继承会引来,二义性 1.源代码 </pre><pre name="code" class="cpp">#include <iostream> using namespace std; class Base { public: virtual void FunTest() { cout << "Base::FunTest () " << endl;