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.我的印象是使用带有对象的点不会导致动态调度。仅 - >带有指针和带引用的点将导致动态调度。
所以我的问题是这段代码是否可移植?
答案 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();
编译器可以直接调用正确的函数,因为它可以在编译时告诉对象类型。