智能指针可以放到容器中么

在C++标准中,一个STL对象是可以“拷贝构造”和“赋值”,而且当一个源对象复制到目标对象后 ,源对象的状态通常是不会改变的。

但是,这不适用于auto_ptr(智能指针)。因为一个auto_ptr对象拷贝或赋值到另一个对象时会使源对象产生预期变动之外的变化。

比如说下面的代码:

class Foo{};

std::vector  < std::auto_ptr <Foo> > vf; // 声明 auto_ptr类型向量元素

// 填写 vf

int fun()

{

  std::auto_ptr <Foo> temp = vf[0]; // vf[0] 变成 null

}

在fun函数中,当temp被初始化时,vf[0]的指针将变成空。如果有其他地方使用了vf[0],那么后面任何对vf[0]的调用都将导致程序的运行崩溃。另外,在您从上面的vector容器中复制元素时,这种情况极有可能会发生。即使代码中没有执行任何显式的拷贝操作或赋值操作,但使用了算法如std::swap()和std::random_shuffle()时,都回出现奔溃。因为这些算法都会创建一个或多个对象的临时副本。另外,vector容器的某些成员函数也会创建一个或多个对象的临时副本,这就会干掉原有的对象指针。以致任何对容器中对象的后续操作都将带来的不确定的后果。

引发这个问题的原因是auto_ptr指针的唯一性即一个对象只能有一个auto_ptr指针所指向它。因此,当auto_ptr以传值方式被复制给另外一个对象时,源对象就放弃了对象的拥有权,把它转移到目标对象上。

同样因为这个问题,应该尽量不在函数的参数中使用auto_ptr指针,也不要通过引用来传递auto_ptr。

PS:  Visual C++种,在STL容器中使用auto_ptr时,可能不会遇到过任何问题是因为在Visual C++中auto_ptr的实现已经过时,而且依赖在一个过时规范上。如果厂商决定赶上当前的最新ANSI/ISO C++标准,并相应地改变它的标准库,在STL容器中使用auto_ptr将会导致严重故障。

猜你喜欢

转载自blog.csdn.net/weixin_41066529/article/details/89844156