这是可移植C++代码吗?
Is this C++ code portable?
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,都调用 B::p rint。几乎怀疑我的C++101。我的印象是,在对象上使用点不会导致动态调度。只有带有指针的 -> 和带有引用的点才会产生动态调度。
所以我的问题是这段代码是否可移植?
a[0]
与*a
相同,并且该表达式是对A
的引用,并且虚拟调度通过引用发生,就像它通过指针一样。 a->print()
和(*a).print()
是完全相同的。
它是可移植的。 a[0] 返回一个引用,引用也使用动态调度。
是的。相当于——
a->print();
它是可移植的,行为定义明确。 指针上的operator[]
只执行指针算术和取消引用。它正在向指针添加0 * sizeof(A)
,因此从某种意义上说,这是一个"危险"的操作,因为任何其他值,但 0 会失败(在 B 数组上(,但由于 0 * sizeof(A( 为 0,在这种情况下,您可以,因为它添加了 0。
多态性适用于引用和指针。
将 a[0]
与指针一起使用是明确定义的,其含义与 *(a + 0)
相同。这就是内置[]
运算符的工作方式。
关于编译器在没有多态性时不需要使用动态调度,您说得对了一部分。不过,这只是一个常见的优化,语言不需要。
当代码为
A a;
a.print();
编译器可以直接调用正确的函数,因为它可以在编译时告诉对象类型。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值