Gio*_*Gio 14 c++ inheritance pointers
我被问到这个面试问题,我弄错了."输出是什么":我的答案是135,实际输出是136.这意味着指向两个父类的指针不相等,即使它们通过了等于子类的先前测试.我以为我理解了c ++指针,但这让我难以理解.虽然我想我知道发生了什么,但我不确定为什么.那里有哪些c ++专家可以提供技术解释?看来前两个比较本质上更合乎逻辑,而最后一个比较更具文字性......
#include <iostream>
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 c;
A *pa = &c;
B *pb = &c;
const int x = (pa == &c) ? 1 : 2;
const int y = (pb == &c) ? 3 : 4;
const int z = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb)) ? 5 : 6;
std::cout << x << y << z << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
也许如果你打印出来pa
,pb
它会更清楚发生了什么.
std::cout << "A: " << pa << std::endl;
std::cout << "B: " << pb << std::endl;
std::cout << "C: " << &c << std::endl;
Run Code Online (Sandbox Code Playgroud)
在最后运行这个main
给了我
A: 0xbfef54e0
B: 0xbfef54e4
C: 0xbfef54e0
Run Code Online (Sandbox Code Playgroud)
(你的输出可能会有所不同,重要的是它们并不完全相同)
这是因为C
对象在内存中的表示方式.由于a C
既是a又是A
a B
,它需要拥有每个部分的数据成员.真正的布局C
是这样的(忽略填充):
int A::m_i;
double B::m_d;
char C::m_c;
Run Code Online (Sandbox Code Playgroud)
将a转换为a C*
时A*
,编译器知道该A
部件从偏移量0开始,因此指针值不会改变.为了C*
给B*
它需要抵消sizeof(int)
(加垫).这种偏移处理是自动完成的,用于计算x
和y
.对于z
它被忽略,因为您使用reinterpret_cast