在c ++中禁用复制构造函数并使用Object

时间:2016-05-26 10:06:22

标签: c++

使用以下代码:

#include <iostream>


class A
{
    public:
        A(int truc) : truc(truc) {}
        A(const A & other) = delete;
    private:
        int truc;
};

class B
{
    public:
        B(int machin, A a) : machin(machin), a(a) {}
    private:
        int machin;
        A a;
};

int main()
{
  A a(10);      
  B b(2,a);
  return 0;
}

我收到编译错误“错误:使用已删除的函数'A :: A(const A&amp;)”

如果我仍然希望A类无法复制,我该如何解决这个问题呢?

3 个答案:

答案 0 :(得分:2)

AB::B(int machin, A a)的{​​{1}}是主要问题,请B::B(int machin, A& a)B::B(int machin, const A& a)。 这同样适用于构造函数体内对字段的赋值。因此,班级B中的字段声明应分别为A& a;const A& a;

但是,您可能还想删除赋值运算符:A& operator=( const A& ) = delete;

看一下提升non-copyable

它的实现还取决于C ++ 11是否可用:http://www.boost.org/doc/libs/1_60_0/boost/core/noncopyable.hpp

答案 1 :(得分:1)

B的构造函数通过值 - &gt;获取类型A的对象创建新对象(副本)

B(...,A a) ...
       ^^^^ pass by value

通过引用传递不会创建新对象(副本)。

B(...,A &a)...
       ^^^^^ pass by reference -> no copy

此外,这意味着您无法将其作为对象B存储在A a中,因为这将再次创建新对象(副本),你'我必须将它存储为参考。

这可能会导致一些问题:

B* createNewObject()
{
   A a(...); //local object is created
   B* ptr = new B(...,a); // reference in B now refers to local object
}// However, here is local object destroyed, so reference in B is now invalid (dangling reference)

int main()
{
   B *pb = createNewObject();
   //Any operation on B working with that invalid reference causes UNDEFINED BEHAVIOUR
}

另外,请记住,a中的任何更改也会更改您传递的对象(因为该引用指的是您传递的同一对象)。

答案 2 :(得分:1)

考虑到复制的替代方法正在移动,您需要:

   B(int machin, A&& a) : machin(machin), a(a) {}

正确地禁止A a(10); B b(2,a); a的副本。你现在需要std::move(a)