因爲設備限制,我現在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等函數的過程中就默默失效了。