派生したクラスの基底クラスを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などにも代入することができるのです。
しかも、所有権が移ったりしないので安心して使用できます。
(メモリリークを起こりにくくするには? の補足参照)
使用上の注意点は、
メモリリークを起こりにくくするには? の漏補も参照ください。
参考: