两个不同的继承指针地址如何相等?

时间:2016-04-08 19:12:49

标签: c++ pointers inheritance

阅读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

3 个答案:

答案 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)