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

因为设备限制,我现在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: 1
auto_vec[1]->d: 1
auto_vec[2]->d: 1
auto_vec[3]->d: 1
auto_vec[4]->d: 1
auto_vec[5]->d: 1
auto_vec[6]->d: 1
auto_vec[7]->d: 1
auto_vec[8]->d: 1
auto_vec[9]->d: 1
D destruction
D destruction
D destruction
D destruction
D destruction
D destruction
D destruction
D destruction
D destruction
D 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(): 0041C930
auto_vec[1].get(): 0041C9B0
auto_vec[2].get(): 0041C970
do nothing
D destruction
do nothing
D destruction
do nothing
D destruction
auto_vec[0].get(): 00000000
auto_vec[1].get(): 00000000
auto_vec[2].get(): 00000000

auto_vec[0].get(): 0041C930
auto_vec[1].get(): 0041C970
auto_vec[2].get(): 0041C9B0
D destruction
D destruction
D destruction
auto_vec[0].get(): 00000000
auto_vec[1].get(): 00000000
auto_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等函数的过程中就默默失效了。

你可能感兴趣的:(auto_ptr作为vector的元素会出现什么情况)