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又是Aa 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
| 归档时间: |
|
| 查看次数: |
355 次 |
| 最近记录: |