关于指针比较(涉及的是对象同一性的问题)

这个问题我是在《C++必知必会》条款28里面看到的。C++指针比较的不是地址,而是对象同一性问题。即指针地址可以不同,而比较的结果却相同,因为它们指向的是同一个对象。

我们可以先看看在类的继承关系中,这种情况表现的形式。先上代码:

#include <iostream>
using namespace std;

class a
{
    private:
        int m_a;
};

class b
{
    private:
        int m_b;
};

class c : public a, public b
{
    private:
        int m_c;
};


int main()
{
    c* cc = new c;
    a* aa = cc; 
    b* bb = cc;                                                                                                                                              

    cout << "bb:" << bb << ",aa:" << aa << endl;
    if (cc == aa) 
    {   
        cout << "cc:" << cc << ",aa:" << aa << endl;
    }   
    if (cc == bb) 
    {   
        cout << "cc:" << cc << ",bb:" << bb << endl;
    }   
    return 0;
}
在上面的派生关系中c同时派生于a,b。并且由于是公有派生,所以在c的对象内部都存在a,b对象的实体,从而也就存在c到任何一个基类的预定义转化。

那么当我们写下b* bb = cc;时,bb所指向的是否跟是cc所指向的地址一样呢?其实不然。如果了解了对象内存模型之后,你就知道:实际上在写下这条语句时,bb实际指向的是cc所指向的对象在内存中基类b的副本的地址。同样aa也是如此。

那么如果是这样的话。“cc == aa”的结果是true还是false呢?

现在就进入本文所讲的重点:地址可以不同,而比较的结果却相同,因为它们指向的是同一个对象。

运行一下代码你就会发现,答案是肯定的。为什么呢?

由于cc和aa其实指向的是同一个对象,编译器必须保证他们相比较的结果是true。打个比方:我和你去坐地铁,我在10号车厢,你在20号车厢,你能说我们不在同一辆地铁上么?其实在做指针比较的时候,由于编译器知道指针的类型信息,所以它会自动调整一定的偏移量来完成比较操作。如:表达式cc == bb,编译完成后,可能翻译为:cc?(cc+delta == bb) : (bb == 0),delta就是基类子对象在派生类中中的偏移量。

最后说明一下:在处理类对象指针的时候一定要小心,避免转化成空指针,这样就会丢失类型信息。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值