使用以下代码:
#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类无法复制,我该如何解决这个问题呢?
答案 0 :(得分:2)
A
中B::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)
。