#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;
}
此代码打印出136
,这表示第一个等式为真,第二个也不是第三个。由于pa
和pb
都设置为&c
,前两个会有意义,但为什么第三个等式会为假?
我在Visual C ++ 2012中运行此代码,并使用调试器检查地址:
pa == 0x003bfc90
pb == 0x003bfc98
&c == 0x003bfc90
显然,pa
和pb
并未指向相同的地址,这意味着第三个等式应为假(并且是)。但那么为什么前两个是真的呢?你能解释一下这里发生了什么吗?
答案 0 :(得分:7)
两个指针确实具有不同的值,因为它们指向c
的不同子对象;这两个对象必须存在于不同的位置。
如果没有reinterpret_cast
,则相等比较首先查找到相同指针类型的合适转换。这会将&c
从C*
转换为B*
,方法是修改指针值以指向B
的{{1}}子对象 - 与应用的转换完全相同在初始化c
时。在转换之后,两个指针都具有相同的值,因此比较相等。
pb
表示指针应转换为目标类型而不修改其值,无论该转换是否有意义。因此,在转换之后,指针仍然具有不同的值,并且比较不相等。