【问题标题】:Is it legal to construct data members of a struct separately?单独构造结构的数据成员是否合法?
【发布时间】:2020-03-06 00:07:10
【问题描述】:
class A;
class B;
//we have void *p pointing to enough free memory initially
std::pair<A,B> *pp=static_cast<std::pair<A,B> *>(p);
new (&pp->first) A(/*...*/);
new (&pp->second) B(/*...*/);

上面的代码执行后,*pp 是否保证处于有效状态?我知道答案对于我测试过的每个编译器都是正确的,但问题是根据标准这是否合法,因此。此外,如果AB 在C++98/03 中不可移动,是否还有其他方法可以获得这样的pair? (感谢@StoryTeller-UnslanderMonica,std::pair 自 C++11 起就有一个分段构造函数)

【问题讨论】:

  • 嗯。分段放置新。我敢打赌它没有指定;这东西通常是。但我对你的问题是……为什么???为什么你认为你需要这样做?如果你必须问一个构造是否合法,你不应该使用它,因为如果没有其他的话就不清楚(但还有很多其他的)
  • 我假设AB 是完整类型,对吧?
  • 嗯,std::pair 有一个构造函数可以做到这一点(分段构造)。所以是的,为什么?
  • @Chipster 是的,它们是完整的类型
  • @StoryTeller-UnslanderMonica 不是完全这个;该对本身正在由上述相同的构造函数正确构造。在 OP 的示例中并非如此。从对象模型的角度来看,父对象仍然不存在。就是这个问题。

标签: c++ struct language-lawyer c++98 placement-new


【解决方案1】:

“访问”不存在的pair 对象的成员是根据 [basic.life]/5 的未定义行为; pair 绝不是 POD 类(具​​有用户声明的构造函数),因此指向其生命周期外存储的指针可能不会用于其成员。尚不清楚形成指向成员的指针是否已经未定义,或者new 是否已定义。

也没有办法在 C++98 中构造一对不可复制(当然不是可移动)类型——这就是为什么添加分段构造函数的原因和 移动语义。

【讨论】:

    【解决方案2】:

    一个更简单的问题:使用文字字符串是否定义良好?

    甚至没有,因为它的生命周期没有定义。您不能在符合代码中使用字符串文字。

    因此,从不花时间明确定义字符串文字的委员会显然没有费心指定 哪些 类类型的对象可以通过放置其子对象的新对象来存在 - 显然是多态对象不能这样创建!

    该标准甚至懒得描述联合的语义。

    关于生命周期的标准无处不在,这不仅仅是社论:它反映了严肃的人之间对于生命周期的开始、对象是什么、左值是什么等方面的深刻分歧。

    值得注意的是,人们有各种错误或矛盾的直觉:

    • 一次调用malloc 无法创建无限数量的对象
    • 左值指的是对象
    • 重叠的对象不符合对象模型
    • 一个未命名的对象只能由new或编译器(临时)创建 ...

    【讨论】:

    • 描述了union 的语义。他们只是不是一群人错误地认为的那样。
    • 我不知道你在处理字符串文字方面的情况
    • 对象是存储区域(ref),而文字不是这样。但是,如果您担心取消引用等:“评估字符串文字会产生具有静态存储持续时间的字符串文字对象” (ref) 然后应用通常的规则
    • 无论如何,这甚至没有试图解决所写的问题。
    • @LightnessRaceswithMonica 何时创建字符串文字? “那么通常的规则适用”哪些规则?
    猜你喜欢
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    相关资源
    最近更新 更多