阅读C++: Comparing pointers of base and derived classes后,我认为这不会奏效。
当我执行此操作时,c_as_b
和&c
的打印地址不同,那么为什么打印“似乎可以安全地比较同一层次结构中的指针”?除了可能导致真实的打印地址之外还要进行哪些比较?
你能给出一个类似的小例子==
导致错误吗?
#include <iostream>
using namespace std;
struct A { std::string s; };
struct B { int i; };
struct C : A, B { double d; };
int main() {
C c;
B* c_as_b = &c;
A* c_as_a = &c;
cout << "c_as_a: " << c_as_a << endl
<< "c_as_b: " << c_as_b << endl
<< "&c: " << &c << endl;
cout << (c_as_b == &c ? "seems safe to compare pointers in same hierarchy" : "definately not safe") << endl;
return 0;
}
示例输出:
c_as_a: 0xbfb98f10
c_as_b: 0xbfb98f14
&c: 0xbfb98f10
seems safe to compare pointers in same hierarchy
答案 0 :(得分:5)
指针等式比较c_as_b == &c
将执行隐式指针转换。来自[expr.eq]:
如果至少有一个操作数是指针,指针转换(4.10),函数指针转换(4.12), 并且对两个操作数执行限定转换(4.4)以将它们带到它们的复合指针 类型(第5条)。
基本上,&c
将转换为B*
,以便进行比较。在这一点上,它与c_as_b
完全相同(因为这就是你开始使用指针的方式),所以他们比较相等。
答案 1 :(得分:1)
在此示例中,c
静态向上转换为B,然后与c_as_b
进行比较,产生true。
答案 2 :(得分:-1)
要回答没人提及的问题部分:你能给出一个类似的小例子,其中==会导致错误吗?
下面是一个类似的示例,其中==
导致false,使用dynamic_cast<void*>
使得相同的比较成立,并且注释掉了==
导致编译时错误的方式:
#include <iostream>
using namespace std;
struct A { virtual ~A() {} };
struct B : A { };
struct C : A { };
struct D : B, C { };
int main() {
D d;
C* c = &d;
B* b = &d;
A* a_through_b = b; // &d results in error: 'A' is an ambiguous base of 'D'
A* a_through_c = c;
cout << "&d: " << &d << endl
<< "c : " << c << endl
<< "b : " << b << endl
<< "a_through_b : " << a_through_b << endl
<< "a_through_c : " << a_through_c << endl;
cout << (a_through_b == a_through_c ? "a_through_b == a_through_c" : "a_through_b != a_through_c") << endl;
cout << (dynamic_cast<void*>(a_through_b) == dynamic_cast<void*>(a_through_c) ? "dynamic_cast<void*>(a_through_b) == dynamic_cast<void*>(a_through_c)" : "dynamic_cast<void*>(a_through_b) != dynamic_cast<void*>(a_through_c)") << endl;
//cout << (a_through_c == &d) << endl; // error: 'A' is an ambiguous base of 'D'
cout << (dynamic_cast<void*>(a_through_c) == dynamic_cast<void*>(&d) ? "dynamic_cast<void*>(a_through_c) == dynamic_cast<void*>(&d)" : "dynamic_cast<void*>(a_through_c) != dynamic_cast<void*>(&d)") << endl;
return 0;
}
示例输出:
&d: 0xbff6d558
c : 0xbff6d55c
b : 0xbff6d558
a_through_b : 0xbff6d558
a_through_c : 0xbff6d55c
a_through_b != a_through_c
dynamic_cast<void*>(a_through_b) == dynamic_cast<void*>(a_through_c)
dynamic_cast<void*>(a_through_c) == dynamic_cast<void*>(&d)