这是C++吗?代码可移植?
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。我的印象是,对对象使用点不会导致动态调度。仅->带有指针和带有引用的点将导致动态调度。
所以我的问题是这段代码是否可移植?
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.
}
All three g++, vs2010, clang call B::print. Almost doubting my C++ 101. I was under the impression that using a dot with an object does not result in a dynamic dispatch. Only -> with a pointer and dot with a reference will result in a dynamic dispatch.
So my question is whether this code is portable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
a[0]
与*a
相同,该表达式是对A
的引用,并且虚拟调度通过引用发生,就像通过指针一样。a->print()
和(*a).print()
完全相同。a[0]
is the same as*a
, and that expression is a reference to anA
, and virtual dispatch happens through references just as it does through pointers.a->print()
and(*a).print()
are entirely identical.它是便携式的。 a[0] 返回一个引用,并且引用也使用动态调度。
It's portable. a[0] returns a reference, and references use dynamic dispatch as well.
是的。它相当于 -
Yes. It is equivalent to -
它是可移植的并且行为是明确定义的。指针上的
operator[]
仅执行指针算术和取消引用。它将0 * sizeof(A)
添加到指针,因此从某种意义上说,它是一个“危险”操作,因为除 0 之外的任何其他值都会失败(在 B 数组上),但作为 0 * sizeof(A) 是 0,在这种情况下你没问题,因为它添加了 0。多态性适用于引用和指针。
It is portable and the behaviour is well-defined.
operator[]
on a pointer just does pointer arithmetic and a dereference. It is adding0 * sizeof(A)
to the pointer, so in a sense it is a "dangerous" operation as any other value but 0 would fail (on an array of Bs), but as 0 * sizeof(A) is 0, in this case you're ok because it's adding 0.Polymorphism works on references as well as pointers.
将
a[0]
与指针一起使用是明确定义的,其含义与*(a + 0)
相同。这就是内置[]
运算符的工作原理。关于编译器在没有多态性时不需要使用动态分派,您的说法部分正确。但这只是一种常见的优化,并不是语言所要求的。
当代码是
编译器可以直接调用正确的函数,因为它可以在编译时告诉对象类型。
Using
a[0]
with a pointer is well defined and means the same as*(a + 0)
. That's how the built in[]
operator works.You are partly right about the compiler not needing to use dynamic dispatch when there is no polymorphism. This is just a common optimization though, and not required by the language.
When the code is
the compiler can call the correct function directly, because it can tell the object type at compile time.