栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

被遗弃的多重继承下

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

被遗弃的多重继承下

多重继承的问题三:
多重继承可能产生多个虚函数表(baseA和baseB存在虚函数,有虚函数表,Derived将继承两个虚函数表)
编程实验:多重继承问题三

#include 
#include 

using namespace std;

class baseA
{
public:
    virtual void funcA()
    {
        cout << "baseA::funcA()" << endl;
    }
};

class baseB
{
public:
    virtual void funcB()
    {
        cout << "baseB::funcB()" << endl;
    }
};

class Derived : public baseA, public baseB
{

};

int main()
{
    Derived d;
    cout << "sizeof(d) = " << sizeof(d) << endl;

    return 0;
}


因为Derived继承了两个虚函数表,Derived内部有两个虚函数表指针,因此创建对象的时候这两个成员会指向不同的虚函数表,两个指针16个字节

#include 
#include 

using namespace std;

class baseA
{
public:
    virtual void funcA()
    {
        cout << "baseA::funcA()" << endl;
    }
};

class baseB
{
public:
    virtual void funcB()
    {
        cout << "baseB::funcB()" << endl;
    }
};

class Derived : public baseA, public baseB
{

};

int main()
{
    Derived d;
    baseA* pa = &d;
    baseB* pb = &d;
    baseB* pbb = (baseB*)pa;
    cout << "sizeof(d) = " << sizeof(d) << endl;

    cout << "using pa to call funcA()..." << endl;
    pa->funcA();

    cout << "using pb to call funcB()..." << endl;
    pb->funcB();

    cout << "using pbb to call funcB()..." << endl;
    pbb->funcB();

    return 0;
}

竟然调用了funcA,不是funcB。
解决方案:需要进行强制类型转换时,C++中推荐使用新式类型转换关键字!!

#include 
#include 

using namespace std;

class baseA
{
public:
    virtual void funcA()
    {
        cout << "baseA::funcA()" << endl;
    }
};

class baseB
{
public:
    virtual void funcB()
    {
        cout << "baseB::funcB()" << endl;
    }
};

class Derived : public baseA, public baseB
{

};

int main()
{
    Derived d;
    baseA* pa = &d;
    baseB* pb = &d;
    baseB* paa = (baseB*)pa;
    baseB* pbb = dynamic_cast(pa);  //error
    cout << "sizeof(d) = " << sizeof(d) << endl;

    cout << "using pa to call funcA()..." << endl;
    pa->funcA();

    cout << "using pb to call funcB()..." << endl;
    pb->funcB();

    cout << "using pbb to call funcB()..." << endl;
    pbb->funcB();

    cout << "pa = " << pa << endl;
    cout << "pb = " << pb << endl;
    cout << "paa = " << paa << endl;
    cout << "pbb = " << pbb << endl;

    return 0;
}


正确的使用多重继承
工程开发中的“多重继承”方式:
单继承某个类+实现(多个)接口
实验编程:正确的多继承方式

#include 
#include 

using namespace std;

class base
{
protected:
    int mi;
public:
    base(int i)
    {
        mi = i;
    }
    int getI()
    {
        return mi;
    }
    bool equal(base* obj)
    {
        return (this == obj);
    }
};

class Interface1
{
public:
    virtual void add(int i) = 0;
    virtual void minus(int i) = 0;
};

class Interface2
{
public:
    virtual void multiply(int i) = 0;
    virtual void divide(int i) = 0;
};

class Detived : public base, public Interface1, public Interface2
{
public:
    Detived(int i) : base(i)
    {

    }

    void add(int i)
    {
        mi += i;
    }

    void minus(int i)
    {
        mi -= i;
    }

    void multiply(int i)
    {
        mi *= i;
    }

    void divide(int i)
    {
        if( i != 0 )
        {
            mi /= i;
        }
    }
};

int main()
{
    Detived d(100);
    Detived* p = &d;
    Interface1* pInt1 = &d;
    Interface2* pInt2 = &d;

    cout << "p->getI() = " << p->getI() << endl;

    pInt1->add(10);
    pInt2->divide(11);
    pInt1->minus(5);
    pInt2->multiply(8);

    cout << "p->getI() = " << p->getI() << endl;

    cout << "pInt1 == p :" <equal(dynamic_cast(pInt1)) << endl;
    cout << "pInt2 == p :" <equal(dynamic_cast(pInt2)) << endl;

    return 0;
}


一些有用的工程建议:
(1)先继承自一个父类,然后实现多个接口
(2)父类中提供equal()成员函数
(3)equal()成员函数用于判断指针是否指向当前对象
(4)与多重继承相关的强制类型转换用dynamic_cast完成

小结:
(1)多继承中可能出现多个虚函数表指针
(2)工程开发中采用单继承多接口的方式使用多继承
(3)父类提供成员函数用于判断指针是否指向当前对象

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/656852.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号