地址、reinterpret_cast和多重继承
Addresses, reinterpret_cast and multiple inheritance
谁能解释一下以下代码的行为?
- 为什么我们在第一种情况下有
b = 3
,即b2 == &d
是真的? - 为什么在案例 2 中可以?我打印了
b2
和d
的地址,它们是不同的。
#include <iostream>
using namespace std;
class A
{
public:
A() : m_i(0) { }
protected:
int m_i;
};
class B
{
public:
B() : m_d(0.0) { }
protected:
double m_d;
};
class C
: public A
, public B
{
public:
C() : m_c('a') { }
private:
char m_c;
};
int main()
{
C d;
B *b2 = &d;
cout << &d << endl;
cout << b2 << endl;
const int b = (b2 == &d) ? 3 : 4; ///Case1: b = 3;
const int c = (reinterpret_cast<char*>(b2) == reinterpret_cast<char*>(&d)) ? 3 : 4; //Case 2: c = 4;
std::cout << b << c << std::endl;
return 0;
}
d 是 C 型。当您将指向 C 的指针转换为指向 B 的指针时,会对其进行调整,使其指向 C 的 B 子对象(在多重继承中通常需要这种 ajustement,如果 B 不需要,则 A 将有一个,因为 C 从 A 和 B 继承)。 因此,在分配和比较时,调整完成。
在另外两个时间,&d 被转换为 void*(隐式)或 char*(带有 reinterpret_cast),并且没有进行任何调整(您明确要求不对reinterpret_cast进行调整,并且在转换为 void* 时没有理由进行调整,这只会无缘无故地使往返复杂化, 对于 A) 你又会有类似的结果,所以表示是不同的。
顺便说一句,如果您使用 reinterpret_cast<B*>(&d)
,不会再次进行调整,但是将结果用作 B* 会很快导致问题。
在情况 1 中,比较会自动将 C 指针强制转换为 B 指针。在这种情况下,这意味着实际地址会发生变化,因为您使用多重继承,而 B 在基类列表中排名第二。更具体地说,指针必须偏移(至少)sizeof(A)。但是,在第二种情况下,不会执行此类自动转换,因此"A 前缀"使两个指针不相等。
相关文章:
- 关于C++中具有多重继承"this"指针的说明
- C++中模板化异常类的多重继承
- 虚拟继承中是否存在多重继承?
- 如何在 c++ 多重继承中调用父非虚函数?
- 多重继承相同的方法名,没有歧义
- 使用enable_if解决多重继承歧义
- 多重继承导致虚假的模糊虚拟函数过载
- 多重继承和访问不明确的元素
- C++ 多重继承:使用基类 A 的实现实现基类 B 的抽象方法
- 多重继承中的派生类的行为类似于聚合
- 为什么我的 Hippomock 期望在使用多重继承时失败
- 带有此指针的模板类多重继承构造函数不起作用?
- 使用多重继承时出现编译错误
- 增强多重继承的序列化
- 多重继承:跳过'virtual'关键字并拒绝菱形层次结构的使用?
- 仅函数的多重继承 - 没有虚拟和 CRTP
- C++多重继承和鸭子类型
- C++两次从文件保存对象读取多重继承
- 从多重继承中的派生类函数调用适当的父类函数
- C++具有多重继承的构造函数重载解析