我有2个A和B类
//A.h
class A{};
// B.h
typedef unique_ptr<A, AllocateA> APtr;
typedef vector<APtr> BVEC;
class B
{
public:
BVEC vec; //error is here
//....
};
当我编译代码时,我得到unique_ptr....attempting to reference a deleted function
然后我将复制构造函数和赋值运算符添加到B类中,如此
class B
{
public:
BVEC vec; //error is here
//....
B& operator=(B&b);
B(B&b);
};
但我仍然收到相同的错误消息。
答案 0 :(得分:2)
那是因为unique_ptr是......唯一的,它们指向一个对象的整点,当unique_ptr超出范围时 - 它会删除它指向的变量。如果您可以轻松地将指向的变量分配给另一个unique_ptr,那么指向的变量什么时候会被删除?当第一个超出范围或第二个?这里没有“独特性”。
这就是为什么不允许复制或分配unique_ptr,复制ctor和赋值运算符被禁用
你正在寻找shared_ptr。多个shared_ptr可以指向一个变量,当它们全部超出范围时会被删除,某种原始垃圾收集器
答案 1 :(得分:0)
此代码在gcc 4.9.2和Visual Studio 2013上运行良好:
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
using namespace std;
//A.h
class A{
public:
int alpha;
A(int input) : alpha(input){}
};
// B.h
typedef unique_ptr<A> APtr;
typedef vector<APtr> BVEC;
class B
{
public:
BVEC vec;
B(){}
const B& operator=(const B& b){
vec.clear();
for_each(b.vec.cbegin(), b.vec.cend(), [&](const unique_ptr<A>& i){vec.push_back(unique_ptr<A>(new A(*i))); });
return b;
}
B(const B& b){
vec.clear();
for_each(b.vec.cbegin(), b.vec.cend(), [&](const unique_ptr<A>& i){vec.push_back(unique_ptr<A>(new A(*i))); });
}
const B& operator=(B&& b){
vec.resize(b.vec.size());
move(b.vec.begin(), b.vec.end(), vec.begin());
return *this;
}
B(B&& b){
vec.resize(b.vec.size());
move(b.vec.begin(), b.vec.end(), vec.begin());
}
};
int main() {
B foo;
B bar;
for (auto i = 0; i < 10; ++i){
foo.vec.push_back(unique_ptr<A>(new A(i)));
}
bar = foo;
foo.vec.clear();
for (auto& i : bar.vec){
cout << i->alpha << endl;
}
foo = move(bar);
for (auto& i : foo.vec){
cout << i->alpha << endl;
}
return 0;
}
我不知道你在APtr
中用于删除器的内容。 (我在评论中提出了这个问题,但还没有看到回复。)我怀疑如果你为B
编写了你的复制构造函数,并且正确地编写了A
的复制构造函数那么你的问题是与您的删除者AllocateA
。
您可以在我为B
撰写的副本构造函数中看到,我A
为this.vec
中的每个A
动态创建了相同的b.vec
{{1}}。我认为这是你想要的行为。如果您只想移动动态分配,我建议使用移动构造函数as suggested by Michal Walenciak。
修改强> 在审查了OP的标题后,我觉得可能的目的是移动构造函数。所以我也添加了其中一个。