auto_ptr作为vector的元素会出现什么情况

来源:互联网 发布:linux vim 复制行 编辑:程序博客网 时间:2024/04/27 18:25

因为设备限制,我现在windows下进行测试,以下代码全部都在vs2013中运行过

下面是例子1:

#include <stdio.h>#include <iostream>#include <memory>#include <vector>using namespace std;class D{public:D() : d(1) {}~D() { printf("D destruction\n");  }int d;};void AutoPtrInVec(){vector<auto_ptr<D> > auto_vec;for (int i = 0; i < 10; i++)auto_vec.push_back(auto_ptr<D>(new D));for (int i = 0; i < 10; i++)printf("auto_vec[%d]->d: %d\n", i, auto_vec[i]->d);}int _tmain(int argc, _TCHAR* argv[]){AutoPtrInVec();getchar();return 0;}

运行结果为:

auto_vec[0]->d: 1auto_vec[1]->d: 1auto_vec[2]->d: 1auto_vec[3]->d: 1auto_vec[4]->d: 1auto_vec[5]->d: 1auto_vec[6]->d: 1auto_vec[7]->d: 1auto_vec[8]->d: 1auto_vec[9]->d: 1D destructionD destructionD destructionD destructionD destructionD destructionD destructionD destructionD destructionD destruction

结果分析:由上可见,auto_ptr作为vector的元素在上面的例子中并没有出现错误,并不像网上一部分文章说的编译会出错(编译出错我觉得可能是编译器不同导致的结果)。


那么,从以上例子是否就说明auto_ptr可以作为vector的元素吗?答案是否定的,看以下例子:

#include <stdio.h>#include <iostream>#include <memory>#include <vector>using namespace std;class D{public:D() : d(1) {}~D() { printf("D destruction\n");  }int d;};void FunAuto(auto_ptr<D> d){printf("do nothing\n");}void AutoPtrInVec(){vector<auto_ptr<D> > auto_vec;for (int i = 0; i < 3; i++)auto_vec.push_back(auto_ptr<D>(new D));for (int i = 0; i < 3; i++)printf("auto_vec[%d].get(): %p\n", i, auto_vec[i].get());for (int i = 0; i < 3; i++)FunAuto(auto_vec[i]);for (int i = 0; i < 3; i++)printf("auto_vec[%d].get(): %p\n", i, auto_vec[i].get());printf("\n");auto_vec.clear();for (int i = 0; i < 3; i++)auto_vec.push_back(auto_ptr<D>(new D));for (int i = 0; i < 3; i++)printf("auto_vec[%d].get(): %p\n", i, auto_vec[i].get());for (int i = 0; i < 3; i++)auto_ptr<D> temp = auto_vec[i];for (int i = 0; i < 3; i++)printf("auto_vec[%d].get(): %p\n", i, auto_vec[i].get());}int _tmain(int argc, _TCHAR* argv[]){AutoPtrInVec();getchar();return 0;}

运行结果如下:

auto_vec[0].get(): 0041C930auto_vec[1].get(): 0041C9B0auto_vec[2].get(): 0041C970do nothingD destructiondo nothingD destructiondo nothingD destructionauto_vec[0].get(): 00000000auto_vec[1].get(): 00000000auto_vec[2].get(): 00000000auto_vec[0].get(): 0041C930auto_vec[1].get(): 0041C970auto_vec[2].get(): 0041C9B0D destructionD destructionD destructionauto_vec[0].get(): 00000000auto_vec[1].get(): 00000000auto_vec[2].get(): 00000000

根据结果分析: vector中的auto_ptr元素在传值(调用auto_ptr类的拷贝构造函数)和赋值(调用auto_ptr类的赋值操作符)的过程中,会把原来的auto_ptr中成员变量_Myptr的值设置成NULL,这样的话原来的auto_ptr就失效了(关于是如何失效的整体过程可以直接去翻auto_ptr的源代码,这里就不分析了),不能再被访问,vector中的auto_ptr元素在这两个过程中会失效。

       C++标准如是说:“STL元素必须具备拷贝构造和可赋值……”,很显然从上述过程中看出auto_ptr作为vector的元素明显不能达成这个条件,所以任何情况下最好不要把auto_ptr作为vector的元素,它可能在你调用swap、sort等函数的过程中就默默失效了。

0 0
原创粉丝点击