IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 被遗弃的多重继承下 -> 正文阅读

[数据结构与算法]被遗弃的多重继承下

多重继承的问题三:
多重继承可能产生多个虚函数表(BaseA和BaseB存在虚函数,有虚函数表,Derived将继承两个虚函数表)
在这里插入图片描述编程实验:多重继承问题三

#include <iostream>
#include <string>

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 <iostream>
#include <string>

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 <iostream>
#include <string>

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<BaseB*>(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 <iostream>
#include <string>

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 :" <<p->equal(dynamic_cast<Base*>(pInt1)) << endl;
    cout << "pInt2 == p :" <<p->equal(dynamic_cast<Base*>(pInt2)) << endl;

    return 0;
}

在这里插入图片描述
一些有用的工程建议:
(1)先继承自一个父类,然后实现多个接口
(2)父类中提供equal()成员函数
(3)equal()成员函数用于
判断指针是否指向当前对象

(4)与多重继承相关的强制类型转换用dynamic_cast完成

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

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-13 13:06:58  更:2021-12-13 13:09:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:35:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码