遗传的'this'的奇怪行为

时间:2011-10-19 20:03:20

标签: c++ oop inheritance

在以下示例中,我无法理解this的值:

struct A {
  int i;

  void bar() {
    cout << this << endl;
  }
};

struct B : public A {
  virtual void foo() = 0;
};

struct C : public B {
  void foo() {
    printf("hello world!\n");
  }
};

int main (int argc, const char* argv[]) {
  C* c = new C; 
  cout << c << endl;
  c->bar();
  return 0;
}

两次我都将指针打印到控制台,我得到不同的值。我希望它是相同的,因为它们两次都引用相同的实例?!

如果删除虚拟功能或int i中的A,它就会消失。为什么呢?

2 个答案:

答案 0 :(得分:2)

但它指的是不同的东西。

void bar() {
    cout << this << endl;
  }

此处this的类型为A*。它指向对象的A部分。

out << c << endl;

此处cC*,并指向对象的C部分。

如果A对象与C对象完全对齐,则指针是相同的。如果它们没有(就像C包含其他成员(隐藏指向vtable的指针),因此'A'部分偏离较大对象的开头),那么指针不一定相同。

答案 1 :(得分:2)

这是一个编译器优化。 A结构没有任何虚拟方法,因此它不需要v表。没有必要在A类对象中存储指向它的指针。这使得对象布局在类型A和C的对象之间不同,因为C 需要一个v表。编译器通过在调用A方法之前递增 this 来弥补差异。

向A添加任意虚拟方法以使指针匹配。