You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何地址不同的基类指针与派生类指针比较结果相等?

多继承下指针比较为何不会触发断言失败?

C++标准在[expr.eq#3]中对指针比较的定义如下:
否则,若两个指针均为空、均指向同一函数,或均表示同一地址,则它们比较相等。

关于“表示同一地址”,[basic.compound#def:represents_the_address]中的定义为:
指向对象或对象末尾之后的指针类型的值,分别表示该对象占用内存的第一个字节([intro.memory])或该对象占用存储之后内存的第一个字节。34

既然指针比较本质基于地址,那为何如下代码不会断言失败?技术上d_ptr和b_ptr指向的对象地址不同,但编译器似乎能识别它们指向同一个完整对象,这看起来像是基于对象而非地址比较!

struct B { int a;};
struct B1 { int b; };
struct D : B, B1 {};
struct A {};
// ...
D obj;
D *d_ptr = &obj;
B1 *b_ptr = d_ptr;
assert(d_ptr == b_ptr);// 按说应该失败,因为d_ptr和b_ptr指向的对象地址不同!

这是因为C++标准对不同类型指针的比较做了隐式调整。当比较D*和B1*类型的指针时,编译器会先将d_ptr隐式转换为B1*类型(与b_ptr同类型),再进行地址比较。

具体来说,d_ptr指向完整的D对象,当它被转换为B1*时,会自动调整指针值,指向D对象中B1子对象的起始地址——这个地址和b_ptr的地址完全一致。所以转换后的d_ptr和b_ptr表示的是同一个地址,比较结果自然为true,断言不会触发。

你可能误以为是直接比较原始D*和B1*的地址值,但实际上C++的指针相等比较规则要求,当比较不同类型的对象指针时,会先将其中一方转换为另一方的类型(遵循指针转换规则),再基于转换后的指针所表示的地址进行比较。

内容的提问来源于stack exchange,提问作者minex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:05:07