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等函數的過程中就默默失效了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章