复制构造函数..进退两难的境地

Copy Constructors ... A Quandary

本文关键字:进退两难 构造函数 复制      更新时间:2023-10-16

我有一个树类,它声明和定义了move构造函数和move赋值操作符。

为什么编译器觉得需要合成一个复制构造函数,然后抱怨std::unique_ptr有私有成员?

这似乎适得其反。编译器应该不知道没有主体或没有定义的隐藏复制和赋值是为了防止复制std::unique_ptr吗?

并且,为什么声明和定义带有空体的复制构造函数和赋值操作符会使编译器高兴?

当我继续使用这个类编写和构建代码时,这会引起关注吗?

添加

:

  1. 没有源代码,因为没有源代码错误…这是一个问题

  2. 当复制构造函数为私有时,编译器会抱怨,所以我将它们设置为公共;

  3. 我正在使用Visual Studio 2012 Professional IDE及其相关编译器。

为什么编译器生成复制构造函数在移动构造函数的存在?似乎违反直觉,特别是如果复制构造函数没有在第一个地方定义。

<<p> 附加问题/strong>:

嗯,看起来Visual Studio 2012不支持构造函数或赋值操作符上的= delete声明,隐藏我的声明会导致编译器在我的代码中哭泣。我现在该怎么办?我同意(下面)声明不做任何事情的复制构造函数是坏主意,那么我还有什么其他选择呢?

如果真的想要一个小例子,这里就是。我的编译器不支持= delete

class Tree{
    class TreeNode{
         "declaration of unique_ptr, cstrs, move cstrs, hidden copy cstrs"
    };
public:
     "declaration of unique_ptrs, cstrs, move cstrs, copy cstrs <----- compiler 
      complains if hidden"
};

使用boost::variant与

如果没有复制构造函数,编译器将尝试生成一个。默认的复制构造函数相当愚蠢,所以它在类的一些部分出错也就不足为奇了。

定义一个空的复制构造函数会给你一个不做任何事情的复制构造函数,它取代了编译器原本生成的复制构造函数,从而避免了这个问题。

为什么编译器觉得需要合成一个复制构造函数,然后抱怨std::unique_ptr有私有成员?

它不应该,除非你的标准库不兼容,并且为unique_ptr声明了一个私有的而不是删除的复制构造函数;即使这样,也只有在没有声明move构造函数的情况下才应该进行合成。

如果你的类有unique_ptr成员,或者你声明了一个move构造函数,那么它应该报错复制构造函数被删除了;然后,只有当你写的代码试图复制它。

编译器应该不知道没有主体或没有定义的隐藏复制和赋值是为了防止复制std::unique_ptr吗?

这是正确的;只是删除了合成复制构造函数和赋值,而不是没有定义。

并且,为什么声明和定义带有空体的复制构造函数和赋值操作符会使编译器高兴?

因为您显式地说您希望它使用该(空)代码进行复制,而不是它可能(或可能不)隐式生成的任何代码。但这是个坏主意;如果您的类不可复制,那么您希望尝试复制它以生成错误,而不是错误的运行时行为。