• ベストアンサー

スマートポインタの使い方

boost::shared_ptrについてなのですが vector<shared_ptr<CTest>> vec; 上記のベクタの要素を別のクラスからも参照しておきたい場合、 shared_ptr<CTest> p = vec[0]みたいにスマートポインタで持っておくか、 単にCTest* p = vec[0]._Ptrとしてポインタを持っておくのとどちらが良いのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

shared_ptr を使っているならあえてただのポインタにする必要はないと思う. shared_ptr なり weak_ptr なりを使えばいいんじゃない? ああ, shared_ptr に対して _Ptr で「保持するポインタ」を取り出すのは反則だと思うよ. それ用のメンバ関数を使ってやるべき.

noname#115727
質問者

お礼

回答ありがとうございました。 たしかにわざわざポインタ使う必要ないですよね。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • thisをshared_ptrにキャストするには?

    こんにちは。 boost::shared_ptrを使用しているのですが、 boost::shared_ptr< Foo > lpRet ; lpRet = boost::shared_dynamic_cast< Foo, Hoge >( this ) ; のようなthisポインタをキャストしたいのですが、 どのように書けばよろしいのでしょうか?

  • boostスマートポインタ(shared_ptr)を使用した、簡単なフ

    boostスマートポインタ(shared_ptr)を使用した、簡単なファイルの読み込みとループ処理で困っています。 以下に示すような、テキストファイルから情報を読み取って構造体のvectorをつくる処理をshared_ptrを使って行おうとしています。 input.txt-- >Taro /boy /8 years old >Hanako /girl /6 years old /likes candy ----- このファイルの'>'で始まる行は'名前'として、それ以外の '/ 'で始まる行はvectorに入れて、このふたつを個人ごとにまとめて構造体として管理するという形をとりたいと考えています。 つまり構造体の要素は <名前の行> <それ以外の行が入ったベクター> となります。 ファイル読み込みの過程で '>' を認識したらこれらのメモリ領域を確保し、shared_ptrで管理したいと考えています。 出来た構造体をベクターに入れ、ファイル読み込みのあとに出力する、という形でプログラムを以下のように書きました。  #include <string> #include <fstream> #include <iostream> #include <boost/shared_ptr.hpp> using namespace std; //構造体定義  struct my_struct{ std::string name;    std::vector<std::string> vector_of_string;  } ; int main(void){ std::ifstream ifs("input.txt"); //構造体を入れるベクター std::vector<my_struct> vector_of_my_struct; std::string buf; boost::shared_ptr<my_struct> SMARTptr_my_struct(new my_struct); boost::shared_ptr<vector<string>> SMARTptr_vector_of_string(new vector<string>); while(ifs && std::getline(ifs, buf)) { if(buf[0] == '>'){   //構造体の領域を作成 boost::shared_ptr<my_struct> SMARTptr_my_struct(new my_struct); //'/'で始まる行を格納しておくベクター領域の作成 boost::shared_ptr<vector<string>> SMARTptr_vector_of_string(new vector<string>); //構造体に作成されたベクターを入れる (*SMARTptr_my_struct).vector_of_string = *SMARTptr_vector_of_string; //構造体にこの行ををnameとして入れる (*SMARTptr_my_struct).name = buf; //ここで新たに作られた構造体をベクターに入れる vector_of_my_struct.push_back(*SMARTptr_my_struct); } if(buf[0] == '/'){ //この行をstring格納用のベクター(if(buf[0]=='>') ですでに作られている)に入れる (*SMARTptr_vector_of_string).push_back(buf); } この後、構造体のベクターのループから情報を出力しますが字数制限のため省略させていただきます。 input.txtと同じ内容が出力されることを期待したのですが、実際は'>'で始まる名前の行しか出力されません。 どうやらベクターへのpush_backができていないか、そもそもshared_ptrの扱いに根本的な間違いがあるのでは?と思っているのですが、原因がわかりません。環境はVC++2008 express edition, boost 1.38です。 解決方法、原因、アドバイスなど分かりましたらよろしくお願いします。

  • boost::shared_ptr::getにて

    こんにちは。 C++で書かれたプログラムの保守をしています。 以下のような感じで書かれたクラスがあります。 class Foo { public :   Foo(){} ;   virtual ~Foo(){} ;   void Set( boost::shared_ptr< int > pValue )   {     _pValue = pValue.get() ;   } protected :   void* _pValue ; } ; このクラスから _pValue を再び boost::shared_ptr< int > にして取得するにはどうしたら良いのでしょうか? 強引に、 boost::shared_ptr< int > Get( void ) {   boost::shared_ptr< int >  temp ;   temp.reset( (int*)_pValue ) ;   return temp ; } とやっても案の定ダメでした。 void* _pValue の部分はいろいろ使われていて変更できません。 何かよい手段はないものでしょうか?

  • ポインタと二次元配列

    ポインタを習ったんですが、二次元配列を指定する場合はどのようにすればいいのでしょうか? また、別関数でそのポインタを呼びたいのですが。 (例) main関数 char retsu[2][2] = {{2,4},{6,8}}; char *ptr; next関数 上記でいくと「main関数内のchar retsuの二次元配列を*ptrで指定」、「next関数でmain関数で指定した*ptr(retsu[2][2])を参照したい」 という事をしたいのですが、教えて下さい。

  • 参照型を格納できるコンテナについてなど

    ちょっと長文です。下のほうに質問があります。 STLのvectorコンテナを使用しているのですが、 困った事態が発生しています。 自分は、参照型を要素として、持たしたいのですが、 持たすことができません。 なにやら調べてみたところ、STLのコンテナクラスというのは 基本的に「値ベースのコンテナ」らしく、「参照ベースのコンテナ?」 としてコンテナを使うには、ポインタ型を格納して下さい。との ことでした。 ただし、この方法は2重deleteが発生する危険性を孕んでいるので、 Boostのなんかのポインタークラス?のようなものを使えば、 そのような問題に悩まされることないですよー。とありました。 ここで問題なのは、 ・Boostを扱えるだけの知識がない。 ・そもそもBoostを使えるまで環境設定できる自信がない。 ということです。 そのため、普通のポインタを使って実装しようと思うのですが、 そして上記のような問題が出てくるにつれ自分の中では 次のような疑問点が出てきました。 ●質問(1) ・なんで参照型を格納できるコンテナがないのよ!  本当はあったりするんだけども、自分が知らないだけ? ●質問(2) ・関数間でオブジェクトを渡すときには、パフォーマンスとかも  考慮してもconstキーワードを使いつつの参照渡しがよい。と  Effective C++か何かで読んだのですが、コンテナに格納する  場合にはこれは有効ではないのか?  また、オブジェクトは、基本的には、やたらめったら  コピーするものではなく、一つオブジェクト用のメモリ領域を  作ったらそれを流用(ポインタ・参照を使って参照する)した方が、  作り的にきれいな気がするのですが、なにか方針とかあったりする  のでしょうか? 以上長くなってしまいましたが、よろしくお願いいたします。

  • Vectorのポインタが入ったvector

    windows Vista sp1, Visual C++ 2008でC++の勉強をしています。 Vectorへのポインタが入ったvectorを使うプログラムを書いているのですがうまくいかず、困っています。 どういうプログラムかというと、 入力ファイルの">"という記号を区切りとして、その間にある各行をひとまとめのグループとしてvectorにいれます。 さらに各vectorのポインタをべつのvectorに入れます。 最終的に区切りの数だけvectorができ、入力ファイルを読み終わった後に すべてのvectorを"各グループのポインタが入ったvector"からループ処理ですべて出力する、というものです。 /入力ファイル input.txt/ > human cat dog > beetle dragonfly spider > salmon saury catfish > vector1には human cat dog vector2にはbeetle dragonfly spider vector3にはsalmon saury catfish が入り、 別のvectorにそれぞれのvectorのポインタをいれ、 最後にこのvectorをつかって全ファイル内容を出力するというものです。 具体的に書くと、 ">"の区切りごとの各行のstringを入れるvectorとしてeach_vector。 each_vectorのポインタを入れるvectorをvector_of_ptr_each_vectorとします。 ">"を認識するごとに new で each_vectorの領域を確保し、そのポインタをvector_of_ptr_each_vectorに追加していき、">"のない行のstringを each_vectorに入れます。 ファイルの読み込みが終わった後でvector_of_ptr_each_vectorからイテレータを使って各vector(each_vector)の全要素をそれぞれ出力する、というものです。 以下のようにコードを書きました。 #include <fstream> #include <string> #include <vector> #include <iostream> using namespace std; int main( ) { ifstream ifs("input.txt"); string buf; std::vector<string> each_vector; std::vector<std::vector<string> *> vector_of_ptr_each_vector; while(ifs && getline(ifs, buf)) { if(buf[0] == '>'){ std::vector<string>* ptr_eachvector ; ptr_eachvector = new std::vector<string>; each_vector = *ptr_eachvector ; vector_of_ptr_each_vector.push_back(ptr_eachvector) ; } each_vector.push_back(buf) ; } printf("\n output from vector of ptr of vector\n"); std::vector<std::vector<string> *>::iterator it_b = vector_of_ptr_each_vector.begin(); while( it_b != vector_of_ptr_each_vector.end() ) { std::vector<string>::iterator it_c = it_b->begin();    //エラー1 while( it_c != it_b->end() ) //エラー2 { cout << *it_c << endl; ++it_c; } ++it_b; } return 0; } ですが、エラーでビルドされず、 std::vector<string>::iterator it_c = it_b->begin(); の行に関して error C2839: invalid return type 'std::vector<_Ty> **' for overloaded 'operator ->' error C2039: 'begin' : is not a member of 'std::_Vector_iterator<_Ty,_Alloc>' while( it_c != it_b->end() )   の行に関して error C2839: invalid return type 'std::vector<_Ty> **' for overloaded 'operator ->' 1> with 1> [ 1> _Ty=std::string 1> ] error C2039: 'end' : is not a member of 'std::_Vector_iterator<_Ty,_Alloc>' 1> with 1> [ 1> _Ty=std::vector<std::string> , 1> _Alloc=std::allocator<std::vector<std::string> > 1> ] fatal error C1903: unable to recover from previous error(s); stopping compilation というようなエラーが出ます。 vectorのポインタを入れたvectorの扱い、特にイテレータに関して問題があると思うのですが原因が分かりません。 また、new でのeach_vectorの領域確保の方法も怪しいという感じがします。 解決策、アドバイスありましたらよろしくお願いします。

  • 助けてください ポインタと配列

    #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 0}; int i, *ptr; ptr = &a[0]; while (*ptr!= 0){ if(*ptr!=0) *ptr=0; } for (i = 0; i < 5; i++) printf("a[%d]=%2d &a[%d]=%p\n",i,a[i],i,ptr); // 配列aの値とアドレスを表示せよ putchar('\n'); ptr = &a[0]; for (i = 0; i < 5; i++){ printf("ptr値 =%d ptrアドレス =%p \n",*ptr,ptr); ; } // ポインタptr を使用して、修正後の配列aの値とアドレスを表示せよ printf("\n"); return (0); } /* 処理結果 a[0]= 0 &a[0]=0013FF3C a[1]= 2 &a[1]=0013FF3C a[2]= 3 &a[2]=0013FF3C a[3]= 4 &a[3]=0013FF3C a[4]= 0 &a[4]=0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C 続行するには何かキーを押してください . . .*/ 一次元配列a[]の一番目の要素以外を0にするプログラムを作成せよ。 ただし、最後の要素は0とする。 上記の問題文とこの結果は合致しているでしょうか?

  • C++ shared_arrayについて

    C++ の boost ライブラリの shared_array の挙動についての質問です。 int main() { boost::shared_arrray<char> hoge(char[1000]); boost::shared_arrray<char> hoge(char[1000]); boost::shared_arrray<char> hoge(char[1000]); sleep(100); return 0; } というプログラムがあった場合、sleep中のメモリの確保状況はどのようになるのでしょうか? shared_ptr で上記のようなコードを書くと、コンパイラがredeclarationのエラーを吐きますがshared_arrayではコンパイルが通り、動作はします。 しかしながらメモリーリークなどのバグの温床にならないか不安です。 上記のコードは安全なコードなのでしょうか? よろしければどうして前者はコンパイルが通り、後者はエラーとなったかについても言及していただけると嬉しいです。 よろしくお願いします。

  • ポインタと多次元配列についての質問です

    私の使っている本に、 『ポインタを使って多次元配列にアクセスするには、コンパイラが自動で行っていることを手作業で 行わなければなりません。たとえば、次の配列には各列に5つの要素があります。 float balance[10][5]; したがって、ポインタを使ってbalance[3][1]にアクセスするには、次のようなコードを使用 しなければなりません。 float *p; p = (float *) balance; *(p + (3*5) +1) 目的の要素に到達するには、行番号に行の要素数を掛けてから、その要素の行内での番号を 加えなければなりません。上記の例では、balanceをfloat* にキャストする必要がありました。 配列要素を手作業で指定する都合上、ポインタ演算をfloatポインタに基づいて行わなければなりません。 しかし、balanceによって生成されるポインタの型はfloatの2次元配列です。そこでキャストが 必要になるわけです。』 とあります。 【質問1】なぜ、p = (float *) balance; なのか。p = (float) *balance; ではないのか? 【質問2】本文「上記の例では………必要になるわけです。」の意味がわかりません。 未熟者の私ですがどうか教えてください。

  • C++のActiveX DLLでポインタを受け取る

    C++でVB用にポインタをラップするようなクラスを作ろうと思っています。 VBからByRefで変数を受け取って、そのポインタを保持し、 そのポインタの参照先の変数の値を取得したり、代入するメソッドを実装します。 しかし、ポインタを受け取る時点で、正しいポインタが受け取れていないようです。 idlファイルはおよそウィザードに任せていますが、扱うのは初めてなので、 ドのようにすればByRefで正しいポインタを受け取れるのか教えていただけないでしょうか。 --------------------------------------------- VbHelpLibrary.idl ... interface ILongRef : IDispatch{ [propget, id(1), helpstring("プロパティ Ptr")] HRESULT Ptr([out, retval] long *pVal); [propput, id(1), helpstring("プロパティ Ptr")] HRESULT Ptr([in] long* newVal); [propget, id(2), helpstring("プロパティ Value")] HRESULT Value([out, retval] long *pVal); [propput, id(2), helpstring("プロパティ Value")] HRESULT Value([in] long newVal); }; --------------------------------------------- LongRef.cpp STDMETHODIMP CLongRef::get_Ptr(long *pVal){ *pVal = (long)this->m_ptr; return S_OK; } STDMETHODIMP CLongRef::put_Ptr(long *newVal){ this->m_ptr = newVal; //ここでnewValがVarPtr(X)と一致しない //*newVal = 100; //試しにここでこのポインタの先に値を入れてもXは変化しない return S_OK; } STDMETHODIMP CLongRef::get_Value(long *pVal){ *pVal = *m_ptr; return S_OK; } STDMETHODIMP CLongRef::put_Value(long newVal){ *m_ptr = newVal; return S_OK; } --------------------------------------------- Module1.bas Sub Main() Dim X As Long, Y As New LongRef Debug.Print "VarPtr(X) = ", VarPtr(X) Y.Ptr = X Debug.Print "Y.Ptr = ", Y.Ptr --------------------------------------------- 結果 VarPtr(X) = 1308376 Y.Ptr = 1929464