单继承+多接口

多重继承会产生多个虚函数表:

vptr1指向继承自A的虚函数表,vptr2指向继承自B的虚函数表

 

 如果要强制转化一个类到另外一个类用class2* p = dynamic_cast<class2>(p1);

#include <iostream>
#include <string>

using namespace std;

class Parent_1
{
public:
    virtual void funcA() {}
};

class Parent_2
{
public:
    virtual void funcB() {}
};

class Child : public Parent_1, public Parent_2  // 类的内部有两个虚函数表指针
{
};

int main()
{
    Child c;
    
    Parent_1* p1 = &c;  // 指向类的内存中的第一个虚函数表指针
    Parent_2* p2 = &c;  // 指向类的内存中的第二个虚函数表指针
    Parent_2* p21_c = (Parent_2*)p1;    //使用C语言的强制类型转换并不会改变 p1 指针变量的值
    Parent_2* p21_c_plus_plus = dynamic_cast<Parent_2*>(p1);  // 使用C++的强制类型转换会根据转换类型得到对应的地址值
    
    cout << "p1 = " << p1 << endl;                              // 0x7fffc34fde00
    cout << "p2 = " << p2 << endl;                              // 0x7fffc34fde08
    cout << "p21_c = " << p21_c << endl;                           // 0x7fffc34fde00  
    cout << "p21_c_plus_plus = " << p21_c_plus_plus << endl;      // 0x7fffc34fde08
    
    cout << "size of c = " << sizeof(c) << endl;  // 8 + 8 = 16  虚函数表指针(virtual table pointer to parent1) + 虚函数表指针 (virtual table pointer to parent2)
    
    return 0;
}

单继承某个类+实现多个接口:

#include <iostream>
#include <string>

using namespace std;

class Parent
{
protected:
    int a;
public:
    bool equal(Parent* obj)  // 参数指针是否指向当前对象。
    {
        return (this == obj);
    }
};

class Interface1
{
public:
    virtual void Interface1_func() = 0;
};

class Interface2
{
public:
    virtual void Interface2_func() = 0;
};

class Child : public Parent, public Interface1, public Interface2  // 单继承,多接口
{
public:
    void Interface1_func()  { /* 函数实现 */ }
    void Interface2_func()  { /* 函数实现 */ }
};

int main()
{
    Child c;
    Child* p_c = &c;
    Interface1* p_Int1 = &c;  // 用子类初始化父类
    Interface2* p_Int2 = &c;
        
    cout << p_c->equal(dynamic_cast<Parent*>(p_Int1)) << endl; // 通过 dynamic_cast可以将某一类(Interface1)转化为另一类(Parent)
    cout << p_c->equal(dynamic_cast<Parent*>(p_Int2)) << endl;
    
    return 0;
}

 多继承时在子类出现了多个虚函数表指针,通过dynamic_cast进行转换,得到预期的指针值,不会出现二义性。

使用单接口多接口代替多继承,避免了类的虚函数指针的二义性。

原文地址:https://www.cnblogs.com/zsy12138/p/10855634.html