多继承时的指针偏移和判等问题

代码

#include<iostream>
using namespace std;

class A {
  public:
    int _b1;
};
class B {
  public:
    int _b2;
};
class C: public A, public B {
  public:
    int _b3;
};

int main() {
    C c;
    A* p1 = &c; 
    B* p2 = &c;
    C* p3 = &c;
    cout << p1 << endl;
    cout << p2 << endl;
    cout << p3 << endl;
    if (p2 == p3) {
        cout << "p2 == p3" << endl;
    }
    return 0;
}

运行结果

在这里插入图片描述

原因

  1. 导致地址不同的原因是在C进行继承时有一个先后顺序(按照代码的编写顺序),他会先继承A类,再继承B类,最后再实现自己的部分,这就导致了C的对象模型中B类是在中间位置的,ptr1指向了C对象中A的位置,ptr2指向了C对象中B的位置,编译器取的时候进行指针偏移,从而导致了地址不同。
  2. 当判断 ‘==’ 时,会分析两个地址是不是指向了同一个实例对象,如果是,就会做隐式的类型转换 ,然后再判等(虽然地址不同但指向的是同一个实例对象)

所以可以看到,C++中的多继承其实是一个缺陷,后来的Java中取消了多继承。具体的探究学习《深度探索C++对象模型》

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
多继承下,虚函数表的设计确实存在一些问题。由于一个子类可以继承多个父类,每个父类都有自己的虚函数表,这就导致了可能存在多个虚函数表的情况。这样一来,就需要有一种机制来确定使用哪个虚函数表来处理相应的虚函数调用。 一个常见的解决方案是使用虚函数表指针(vptr)来指向正确的虚函数表。子类的对象会包含一个或多个虚函数表指针,每个指针对应一个父类的虚函数表。当调用子类对象的虚函数,编译器会根据具体的函数调用来选择正确的虚函数表指针,从而找到对应的虚函数表进行调用。 然而,多继承下的虚函数表指针的布局和处理并不像单继承那么简单。由于可能存在多个虚函数表指针,它们的排列顺序以及内存布局都会受到编译器和操作系统的影响。这就导致了多继承下虚函数表的布局可能会比较复杂,不同编译器和操作系统可能会有不同的实现方式。 另外,多继承下还存在一个问题是菱形继承(Diamond Inheritance)导致的虚函数表冗余。菱形继承是指一个子类同继承了两个间接父类,并且这两个父类又继承了同一个基类。在这种情况下,子类会继承两份相同的虚函数表,其中一份是冗余的。为了解决这个问题C++中引入了虚函数表指针偏移来消除虚函数表的冗余。 综上所述,在多继承下,虚函数表存在布局复杂性和虚函数表冗余的问题。具体的虚函数表布局和处理方式会受到编译器和操作系统的影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值