MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
C++の基礎 - スマートポインタ(weak ptr)のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
C++の基礎 - スマートポインタ(weak ptr)
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == C++11では、unique_ptr<T>、shared_ptr<T>、weak_ptr<T>の3種のスマートポインタが追加された。<br> これらのスマートポインタは、メモリの動的確保の利用の際に生じる多くの危険性を低減する目的で使用されるが、<br> それぞれ独自の考え方と機能を持っている。<br> <br> 3種のスマートポインタを適切に使い分けることで、安全性と開発速度の向上が見込めるだけでなく、<br> プログラマの意図に合わせてポインタを記述し分けることができる、非常に強力なツールとなる。<br> <br> ここでは、スマートポインタについて初めて学ぶ人を対象に、<br> C++11で追加された3種のスマートポインタの機能と使い方、および3種をどのように考えて使うかについて、初歩的な解説を行う。<br> <br><br> == weak_ptrとは == weak_ptr<T>は、shared_ptr<T>の循環参照によって生じる問題を防ぐために導入されたスマートポインタである。<br> 先の2つのスマートポインタと違い、weak_ptr<T>はメモリへの所有権を持つことはない。<br> その代わりに、weak_ptr<T>はshared_ptr<T>の指すメモリを参照することができる。<br> <br> 循環参照の例で見てみる。<br> <source lang="c++"> #include<memory> class CHoge { public: // shared_ptrで所有権を得る代わりに、weak_ptrで参照する std::weak_ptr<CHoge> ptr; }; int main() { std::shared_ptr<CHoge> pHoge1 = std::make_shared<CHoge>(); std::shared_ptr<CHoge> pHoge2 = std::make_shared<CHoge>(); // Hoge1のweak_ptrで、pHoge2を参照する pHoge1->ptr = pHoge2; // Hoge2のweak_ptrで、pHoge1を参照する pHpge2->ptr = pHoge1; } // 確保したメモリへの所有権はpHoge1、pHoge2しかそれぞれ持っていないので、循環参照が生じず、正しく解放される </source> <br> このように、 weak_ptr<T>は所有権を持たずにメモリへの参照のみ保持することによって、確保したメモリへアクセスするスマートポインタである。<br> 所有権を持たないため、自身が参照しているメモリが解放されてしまうことはあるが、<br> weak_ptr<T>は、すでにshared_ptr<T>によって参照先のメモリが解放されたかどうかを確認することができる。<br> <br><br> == weak_ptrの使い方 == 具体的な使い方を見てみる。<br> weak_ptr<T>は shared_ptr<T>が所有権を持つメモリしか管理できない。<br> <source lang="c++"> // コンストラクタや代入演算子でshared_ptrを受け取る std::shared_ptr<T> sptr = std::make_shared<int>(10); std::weak_ptr<T> wptr1(sptr); std::weak_ptr<T> wptr2; wptr2 = sptr; // ポインタを直接受け取ることはできない // std::weak_ptr<T> wptr3(new int(10)); // コンパイルエラー </source> <br> <source lang="c++"> // weak_ptr<T>は、コピー、ムーブともに使用することができる。 std::shared_ptr<int> sptr = std::make_shared<int>(10); std::weak_ptr<int> wptr1(sptr); // コピーコンストラクタやコピー代入演算子も可能 std::weak_ptr<int> wptr2(wptr1); std::weak_ptr<int> wptr3; wptr3 = wptr1; // ムーブコンストラクタやムーブ代入演算子も可能 // この時、wptr2とwptr3は参照を失う std::weak_ptr<int> wptr4(std::move(wptr2)); std::weak_ptr<int> wptr5; wptr5 = std::move(wptr3); </source> <br> <source lang="c++"> // 参照の開放は、デストラクタやreset関数を使う std::shared_ptr<int> sptr = std::make_shared<int>(10); { std::weak_ptr<int> wptr1(sptr); } // デストラクタで参照を開放 std::weak_ptr<int> wptr2(sptr); // reset関数で明示的に解放 wptr2.reset(); </source> <br> <source lang="c++"> // 所有権はそもそも保持していないので、operator bool()は使用できない std::shared_ptr<int> sptr = std::make_shared<int>(10); std::weak_ptr<int> wptr(sptr); // 参照先が解放されているか確認するには、expired()を使う(戻り値がtrueの場合は解放されている) if(wptr.expired()) { std::cout<<"expired"<<std::endl; } // use_count関数を使って、参照先のメモリに所有権を持つshared_ptr<T>の数を調べることができる std::cout << "use_count = " << wptr.use_count() << std::endl; </source> <br> <source lang="c++"> // 参照するメモリにアクセスするのに、operator*()やoperator->()は使用できない // メモリにアクセスするためには、まず、lock()によって参照先を保持するshared_ptr<T>を取得し、そこからアクセスする // これは、使用中に解放されてしまうのを避けるためである。 std::shared_ptr<int> sptr = std::make_shared<int>(10); std::weak_ptr<int> wptr(sptr); { // lock関数によって、参照先を保持するshared_ptrを取得する std::shared_ptr<int> ptr = wptr.lock(); } </source> <br><br> __FORCETOC__ [[カテゴリ:C++]]
C++の基礎 - スマートポインタ(weak ptr)
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse