c++ 对象模型23

多重继承第二基类堆虚函数支持的影响  this指针调整作用

class Base{
public:
    virtual void f(){cout << "Base::f()" <     virtual void g(){cout << "Base::g()" <     virtual void h(){cout << "Base::h()" <     virtual ~Base(){}
}

class Base2{
public:
    virtual void HBase2(){cout << "Base::HBase2()" <     virtual ~Base2() {}
}

class Derive :public Base, public Base2{
public:
    virtual void i(){cout << "Derive::i()" <     virtual void g(){cout << "Derive::g()" <     void myselffunc(){}    //  只属于Derive的函数
    virtual ~Derive() {}
}

子类继承了几个父类 就有几个虚函数表

多重继承下 有几种情况 第二个或者后续的基类会对虚函数的支持产生影响

this指针调整的目的:
    this指针调整的目的就是让对象指针正确的指向对象首地址
    从而能正确的调用对象的成员函数或者正确的确定数据成员的存储位置
    
    通过指向第二个基类的指针调用继承类的虚函数
    Base2 *base2 = new Derive()
    delete base2;

    一个指向派生类的指针 调用第二个基类中的虚函数
    Derive *pointDerive = new Derive();
    pointDerive->Hbase2();
    
    允许虚函数的返回类型有所变化

class Base{
public:
    virtual void f(){cout << "Base::f()" <     virtual void g(){cout << "Base::g()" <     virtual void h(){cout << "Base::h()" <     virtual ~Base(){}
    virtual Base *clone() const{
        return new Base();
    }
}

class Base2{
public:
    virtual void HBase2(){cout << "Base::HBase2()" <     virtual ~Base2() {}
    virtual Base2 *clone() const{
        return new Base2();
    }
}

class Derive :public Base, public Base2{
public:
    virtual void i(){cout << "Derive::i()" <     virtual void g(){cout << "Derive::g()" <     void myselffunc(){}    //  只属于Derive的函数
    virtual ~Derive() {}
    virtual Derive *clone() const{
        return new Derive();
    }
}

int main(){
    Base2 *pb1 = new Base2()
    Base2 *pb2 = *pb1->clone();

//  执行clone时, pb1 首先会调整this指针指向Derivce对象的首地址  然后调用Derive的clone()

---------------------------------------------------
虚继承下的虚函数

class Base{
public:
    virtual void f(){}
    virtual ~Base(){};
    int m_Base;
}

class Derive: public virtual Base{
public:
    virtual ~Derive(){};
    int m_Derive;
}

int main(){
    cout << sizeof(Derive) < }

内存排列顺序:
    vbptr
    int m_Derive
    vptr
    int m_Base
有了虚继承+虚函数的组合会使内存结构别的超级复杂


---------------------------------------------------


RTTI运行时类型识别,与存储位置介绍

class Base{
public:
    virtual void f(){cout << "Base::f()" <     virtual void g(){cout << "Base::g()" <     virtual void h(){cout << "Base::h()" <     vritual ~Base(){}
}

class Derive :public Base{
public:
    virtual void g(){cout << "Derive::g()" <     void myselffunc(){}    //  只属于Derive的函数
    virtual ~Derive(){}
}

int main(){
    cout << sizeof(Derive) < }

int main(){
    Base *pb = new Derive();
    pb->g()

    Derive myderive;
    Base &interBase = myderive;
    interBase.g();

}

c++ 运行时类型识别 RTTI 要求父类中必须至少有一个虚函数; 如果没有虚函数 那么RTTI就不准确
RTTI就可以在执行期间查询一个多态 指针 或者多态引用
RTTI 的能力考typeid 和 dynamic_cast运算符来体现

cout << typeid(*pb) < cout << typeid(interBase) <

Derive *pDerive = dynamic_cast(*pb);
if(pDerive != NULLL){
    cout << "pb 是 Derive 类型" <     pDerive->myselffunc();
}

---------------------------------------------------


RTTI 实现原理

typeid  返回的是一个常量对象的引用, 这个常量对象的类型一般是type_info (类)记录类相关信息

const std::type_info &tp = typeid(*pb);

 RTTI的测试能力跟基类中是否有虚函数表,如果基类中没有虚函数 也就不存在积累的虚函数表
 RTTI无法获得正确位置 

---------------------------------------------------

        RTTI相关地址  -  >   四字节
vptr -> 虚函数1地址             四字节
        虚函数1地址          四字节
        虚函数1地址          type_info 对象首地址   -> 对象type_info结构信息


------------------------------------------------

rtti的type_info 信息 构造时机
编译后就存在了

你可能感兴趣的:(c++)