zoukankan      html  css  js  c++  java
  • C++ —— 对象指针比较

    在C++中,一个对象可以有多个有效的地址,所以,对于这个时候的比较不是地址问题,而是对象同一性的问题。

    代码如下:

    #include < iostream >
    using namespace std;
    
    class Shape{
        public:
        Shape():a (1){}
    
        private:
        int a;
    };
    
    class Subject{
        public:
        Subject():b (2){}
    
    
        private:
        int b;
    };
    
    class ObservedBlob: public Shape , public Subject{
        private:
        int c;
        public:
        ObservedBlob ():c( 3){}
    };
    
    int main()
    {
        ObservedBlob * ob = new ObservedBlob;
        Shape * s = ob;
        Subject * subj = ob;
    
        cout << ob << endl << s << endl << subj << endl;
    
        cout << (subj == ob) << endl;
    
        return 0;
    }

    以上的代码的运行结果(mingw gcc 4.7.1):
    Result

    那么问题来了,可以看到subj和ob的地址并不相同,但是对指针进行比较的时候却输出了true,这个是为何?

    先看这种继承的内存分布图:
    Memory

    在前面那种布局里面,s和subj分别指向ob中的对应子对象,它们与ob拥有完全不同的地址。

    在后面的布局里面,s对象与subj对象的地址相同,可以看到上图中就是采用这样的布局。

    但是无论是哪种布局,ob、s和subj都指向同样的一个ObservedBlob对象,因此编译器必须要确保ob与s和subj的比较结果都是true。所以编译器通过将参与比较的指针值之一调整一定的偏移量来完成这种比较,比如:
    ob == subj
    可能会被编译器翻译成:ob?(ob + delta == subj) : (subj == 0)

    delta是Subject子对象在ObservedBlob对象的偏移量,换句话说,如果subj和ob都是空的话,那么它们相等,否则ob被调整为指向Subject基类子对象后再和subj进行比较。

    所以最终可以得到一个很重要的经验,一般而言,当我们处理指向对象的指针或者引用的时候,必须小心避免丢失类型信息。

    如果把上面的指针编程void *v = subj然后在判断ob和v的相等情况,就会得到不相等结论。

    如果通过复制到void*指针后,就丢失了类型信息了,编译器这是就只能进行原始地址比较,这样的比较对于指向类的指针来说,很少会是正确的。

  • 相关阅读:
    C语言之数组中你所不在意的重要知识
    Word2007怎样从随意页開始设置页码 word07页码设置毕业论文
    天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,增益其所不能
    高速排序算法
    Cocos2d-x中停止播放背景音乐
    Netflix公司监控内部安全的开源项目
    Linux内核——进程管理与调度
    WebService之Soap头验证入门
    Google搜索解析
    android-sdk-windows版本号下载
  • 原文地址:https://www.cnblogs.com/arrowinmyknee/p/5470388.html
Copyright © 2011-2022 走看看