复制构造函数......一个窘境

时间:2013-03-28 12:01:34

标签: c++ c++11 compiler-errors unique-ptr

我有一个树类,它有移动构造函数和移动赋值运算符声明和定义。

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

这似乎适得其反。如果编译器不知道隐藏的副本和没有正文或没有定义的分配是为了防止尝试复制std::unique_ptr

而且,为什么声明和定义具有空体的复制构造函数和赋值运算符会使编译器满意?

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

附加

  1. 没有源代码,因为没有源代码错误......这是一个问题 这不需要源代码。

  2. 编译器抱怨复制构造函数是私有的,所以我把它们公之于众; 将再次私有化并验证编译器是否可以启动。

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

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

    其他问题

    好吧,似乎Visual Studio 2012不支持=在构造函数或赋值运算符上删除声明并隐藏我的声明会导致编译器在我的代码中哭泣。现在我该怎么做?我同意(下面)声明无所事事的复制构造函数是坏主意所以我还有其他选择吗?

    如果真的渴望小榜样,就在这里。我的编译器不支持= 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与此

    一起使用

2 个答案:

答案 0 :(得分:2)

如果没有复制构造函数,编译器将尝试生成一个。默认的复制构造函数非常愚蠢,因此它会绊倒你的课程并不奇怪。

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

答案 1 :(得分:1)

  

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

除非您的标准库不合规,否则它不应声明unique_ptr的私有而非删除的复制构造函数;即便如此,只有在你没有声明移动构造函数的情况下才应该合成它。

如果您的班级有unique_ptr个成员,或者您声明了移动构造函数,那么它应该会抱怨复制构造函数被删除;然后只有当你编写试图复制它的代码时。

  

如果编译器不知道没有正文或根本没有定义的隐藏副本和作业是为了防止尝试复制std::unique_ptr

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

  

而且,为什么声明和定义具有空体的复制构造函数和赋值运算符会使编译器满意?

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