繁体   English   中英

有没有办法在 C++ 中进行就地成员构造(不复制和破坏对象)?

[英]Is there a way to do in-place member construction in C++ (without copying and destructing an object)?

所以,我终于在我的软件中找到了一个奇怪的崩溃,这是由于我之前遇到的一个问题而发生的:

m_member = Foo(var1, var2)

我意识到这是使用 var1 和 var2 执行 Foo 的构造,通过复制分配将 Foo 的这个实例分配给 m_member,然后删除原始实例。 有没有办法避免这种行为并有类似的东西:

m_member(var1, var2);

我知道这可以在初始化列表中完成,但不幸的是,我正在为已经构建的 object 修改此成员。 有什么想法吗?

奇怪的崩溃......这是因为......我意识到这是使用 var1 和 var2 执行 Foo 的构造,通过复制构造将 Foo 的这个实例分配给 m_member,然后删除原始实例。

如果这样做会导致崩溃,则该成员的 class 的设计被破坏。 可能(但我不能确定)由于未能在赋值运算符中强制执行 class 不变量,这对于防止析构函数具有未定义的行为是必要的。

有没有办法避免这种行为

如果您需要分配成员,那么您必须分配成员。 如果我的怀疑是正确的,您可以通过修复赋值运算符来修复程序。

如果您不需要分配成员,则可以通过不分配来避免此行为。 但是无论如何都要修复赋值运算符。

由于您没有显示 class,我不知道它为什么会损坏,但很可能您应该查看析构函数和赋值运算符并考虑可能导致它们具有未定义行为的情况。

有没有办法避免这种行为并有类似的东西:

 m_member(var1, var2);

这只有在成员初始化时才有可能。

那里有几个选项,假设您的问题来自复制分配:

改用指针类型

m_member更改为Foo* ,或者更好的是std::unique_ptr<Foo> ,以更好地匹配先前的行为,然后执行以下操作:

    m_member = std::make_unique<Foo>(var1, var2);

没有副本,仍然会在 scope 的末尾被销毁,并且鉴于您的问题的描述,这可能意味着您的“Foo”资源将作为指针更有效地管理。

你也可以...

定义移动赋值运算符

现在这意味着您必须定义大 5 ,但定义移动赋值运算符将使您避免复制。

Foo& operator=(const Foo& other)
{
    // Copy the attributes you need to copy
    var1_ = other.var1_;
    var2_ = other.var2_;
    return *this;
}

这将有效地就地修改Foo

修复复制分配?

现在这确实回答了您的问题,但是毫无戒心的开发人员当然会期望这不会崩溃,而且这个问题很可能会出现在其他地方,因为在编写代码和标准算法中经常出现复制分配。 但是这可能无法做到的原因有很多,所以我让你来判断!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM