首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么强制复制省略不适用于潜在重叠的子对象?

为什么强制复制省略不适用于潜在重叠的子对象?
EN

Stack Overflow用户
提问于 2022-08-31 16:43:18
回答 1查看 123关注 0票数 7

背景

强制复制/移动操作可能已经为许多C++程序员所熟悉。从链接文本复制的示例。编译器不得插入副本和移动:

  • 在对象的初始化中,当初始化器表达式是与变量类型相同的类类型(忽略cv限定)的prvalue时:

T =T(T(f();//只调用T的默认构造函数来初始化x

这只能在已知被初始化的对象不是潜在重叠的子对象时才适用:

结构C{ /* .* };C();struct D;D();struct D:C{D():C(f()) {} // no省略,当初始化基类子对象D(int):D(g()) {} / no省略时,因为初始化的D对象可能是其他类}的基类子对象;

在实践中,这是通过给f一个隐藏的额外参数来实现的,它告诉f在哪里构造它的返回值。

问题

为什么潜在重叠的子对象而不是服从强制省略?f没有理由不能直接在D的基类部分构造它的返回值。

EN

回答 1

Stack Overflow用户

发布于 2022-09-10 15:07:41

相关资源如下

以下几点:

  1. f()将调用完整对象(C1)构造函数,而不是基对象(C2)构造函数。这立即排除了对于C具有虚拟基(在这种情况下是C1 != C2)的情况下的复制省略。
  2. 在其他情况下,为了避免复制(物化),C1需要无条件地保留尾垫不动,除非C是POD (在Itanium的情况下)。然而,这是不切实际的保证,因为有时机器指令更有效率时,包括填充,有ABI的考虑,等等。

你的反对意见

D的成员还没有初始化

并不完全正确,因为虚拟基类是在完整对象的末尾分配的:

代码语言:javascript
复制
struct A {
    char i = 5;
    A() {} // to prevent this being a POD for the purpose of layout
};
struct C {
    int j; char s;
    C() { /* ...*/ }
};
struct D : virtual A, C {
    D() : A(), C(f()) {}
};

在这里,A立即在内存中跟随C。稍后,当为f或C的ctors生成代码时,我们无法知道C是否是一个包含虚拟基的完整对象的基。如果让f构造基本对象(在构造A之后发生),我们可能会覆盖重复使用的尾部填充,这就是i所在的位置。

我建议阅读上文第二个环节中的讨论,因为它还涉及切点和修改措辞的方式,以反映目前的实施做法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73559242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档