派生したクラスの基底クラスをvectorに入れたい場合が多々あります。


しかし、標準C++にあるvectorやlistなどには、new したクラスを直接入れられません

なぜなら、以下のように宣言して使用した場合、

vectorのデストラクタでも new string()したオブジェクトが開放されないからです。

vector<string*> vec;

vec.push_back(new string("aiueo"));


そうすると、次に考えるのはstd::auto_ptr<string> をvectorに代入する方法です。

vector<auto_ptr<string> > vec;

vec.push_back(auto_ptr<string>(new string("aiueo")));


実は、これもできません。

C++では、auto_ptrはvectorやlistに入れることができないことになっています。


では、どうしたらよいのでしょう?



【サンプル】

#include <cstdlib>
#include <iostream>
#include <vector>

#include "boost/shared_ptr.hpp"
//

using namespace std;
using namespace boost;


//メイン
int main(int argc, char *argv[])
{
//型宣言
typedef shared_ptr<string> str_ptr;
typedef vector<str_ptr> str_vector;


//テスト値の代入
str_vector vec;
vec.push_back(str_ptr(new string("no.1")));
vec.push_back(str_ptr(new string("no.2")));
vec.push_back(str_ptr(new string("no.3")));


str_vector::iterator ite;

//イテレータは (*ite) が、shared_ptr<string>を返すことに注意
for(ite=vec.begin(); ite!=vec.end(); ++ite)
cout << (*ite)->c_str() << endl;


system("PAUSE");
return EXIT_SUCCESS;
}


【出力】

no.1
no.2
no.3



【説明】

boost::shared_ptrを使用します。

shared_ptrは、vector, listなどにも代入することができるのです。


しかも、所有権が移ったりしないので安心して使用できます。

メモリリークを起こりにくくするには? の補足参照)


使用上の注意点は、

メモリリークを起こりにくくするには? の漏補も参照ください。




参考:

boostとは?