C++对象指针比较比较的并不是地址值

在C++中,在有继承的情况下,一个对象可以有多个有效地址,因同一个子类对象,被不同的父类指针指向时,各个父类指针的值是不同的。分析一段如下代码:

#include <iostream>
#include <assert.h>

using namespace std;

class shape{
private:
  int id;
public:
  shape(){
    id = 1;
  }
};

class subject{
private:
  int id;
public:
  subject(){
    id = 2;
  }
};

class obj : public shape, public subject {
private:
  int id;
public:
  obj(){
    id = 3;
  }
};

int main() {
  shape *shapeptr = NULL;
  subject *subptr = NULL;
  obj *objptr = new obj;

  cout << "shapeptr : " << shapeptr << endl;
  cout << "subptr : " << subptr << endl;
  cout << "objptr : " << objptr << endl;

  cout << "---------------------------------------------------------" << endl;

  shapeptr = objptr;
  subptr = objptr;

  cout << "shapeptr : " << shapeptr << endl;
  cout << "subptr : " << subptr << endl;
  cout << "objptr : " << objptr << endl;

  cout << "---------------------------------------------------------" << endl;

  assert(subptr == objptr);

  cout << "main end!" << endl;
}

不同的电脑以及相同的电脑可能每次运行结果都不相同,在我的电脑上运行结果如下:

shapeptr : 0
subptr : 0
objptr : 0x8c28a10
---------------------------------------------------------
shapeptr : 0x8c28a10
subptr : 0x8c28a14
objptr : 0x8c28a10
---------------------------------------------------------
main end!

通过上面的结果我们可以知道,两个父类指针,同时指向同一个子类对象,shapeptr(父类)的指针值和objptr(子类)的指针值相同,而subptr(父类指针)和objptr(子类)指针值不相同,但是程序最中还是通过了最后的assert(subptr == objptr);,通过我们可以通过分析代码得出对象布局大体如下:

这里写图片描述

这段程序虽然不能说明C++ 中比较指针是对象同一性问题,而不是地址值问题。编译器会根据对象的类型对比较进行翻译,如我们的代码可能就被翻译成如下形式:

//subptr有可能为空指针
subptr ? subptr - sizeof(shape) == objptr : 0;

如果想进一步比较可以通过指针强转,去掉对象类型进行比较,我们在原代码的基础之上添加如下代码:

  void *vptr = subptr;
  assert(vptr == objptr); //断言会失败!

猜你喜欢

转载自blog.csdn.net/u010154685/article/details/54755449