这个C ++代码是否可移植?

时间:2012-01-12 18:53:08

标签: c++ compiler-construction virtual portability

struct A {
  int a;
  virtual void print() {}
};

struct B : A {
  int b;
  virtual void print() {}
};

int main(void)
{
  A *a = new B;
  a[0].print(); // g++, vs2010, clang call B::print.
}

所有三个g ++,vs2010,clang调用B :: print。几乎怀疑我的C ++ 101.我的印象是使用带有对象的点不会导致动态调度。仅 - >带有指针和带引用的点将导致动态调度。

所以我的问题是这段代码是否可移植?

5 个答案:

答案 0 :(得分:14)

a[0]*a相同,该表达式是引用A,虚拟发送通过引用发生,就像通过引用一样指针。 a->print()(*a).print()完全相同。

答案 1 :(得分:4)

它是便携式的。 a [0]返回引用,引用也使用动态分派。

答案 2 :(得分:3)

是。它相当于 -

a->print();

答案 3 :(得分:1)

它是可移植的,行为定义明确。指针上的operator[]只是指针算术和解除引用。它正在向指针添加0 * sizeof(A),所以在某种意义上它是一个“危险”操作,因为任何其他值,但0会失败(在B数组上),但是当0 * sizeof(A)为0时,在这种情况下,你没关系,因为它增加了0。

多态性适用于引用和指针。

答案 4 :(得分:1)

使用带有指针的a[0]定义明确,与*(a + 0)的含义相同。这就是内置[]运算符的工作原理。

在没有多态的情况下,你对需要使用动态调度的编译器是正确的。这只是一种常见的优化,而不是语言所要求的。

当代码

A a;
a.print();

编译器可以直接调用正确的函数,因为它可以在编译时告诉对象类型。