因为std::auto_ptr是转移语义,而STL容器的元素必须是值语义,也就是拷贝语义的。

比如,STL容器都是以副本的形式来保存元素。
std::vector<int> v;
int a = 1;
v.push_back(a);
v[0]也是值为1的int,但不是a..仅仅是一个副本.a的值也并未被改变.

std::auto_ptr<int> p1(new int);
std::auto_ptr<int> p2 = p1;
p2的构造修改了p1的值,使p1交出了对动态分配的int的引用权.此时p1不再引用动态int.这就是转移语义.

另外,std::auto_ptr为了达到转移语义的要求,只提供了这样的一个拷贝构造函数
auto_ptr(auto_ptr&); 而不是通常情况看到的T(const T&); 这就是一个非值语义的表现.

而std::vector因为对元素类型要求是值语义的,所以必须要求元素类型提供T(const T&)的拷贝构造函数.
它不能用于动态创建的数组。 
可能是因为大部分时候用std::vector就很合适了,所以没有与auto_ptr相对应的auto_array。不过如果真的有特殊需要的话,也很容易仿照 std::auto_ptr写个auto_array。

使用auto_ptr要知道:
1. 智能指针不能共享指向对象的所有权
2. 智能指针不能指向数组。因为其实现中调用的是delete而非delete[]
3. 智能指针不能作为容器类的元素。

 

因为std::auto_ptr是转移语义,而STL容器的元素必须是值语义,也就是拷贝语义的。

比如,STL容器都是以副本的形式来保存元素。
std::vector<int> v;
int a = 1;
v.push_back(a);
v[0]也是值为1的int,但不是a..仅仅是一个副本.a的值也并未被改变.

再来看std::auto_ptr
std::auto_ptr<int> p1(new int);
std::auto_ptr<int> p2 = p1;
p2的构造修改了p1的值,使p1交出了对动态分配的int的引用权.此时p1不再引用动态int.这就是转移语义.

从语义上,这两个就不兼容.
另外,std::auto_ptr为了达到转移语义的要求,只提供了这样的一个拷贝构造函数
auto_ptr(auto_ptr&); 而不是通常情况看到的T(const T&); 这就是一个非值语义的表现.

而std::vector因为对元素类型要求是值语义的,所以必须要求元素类型提供T(const T&)的拷贝构造函数.

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐