「ブーストC ++ライブラリ」第一章スマートポインタ

Boost.SmartPointersはヘルプが動的に割り当てられたオブジェクトを管理、それらはメモリデストラクタでスマートポインタによって解放され、スマートポインタを数多く提供しています。以来デストラクタが動的に割り当てられたオブジェクトの管理がリリース保証できるように、スマートポインタのライフサイクルの終了時に実行されます。手動で削除することを忘れていてもこれは、メモリリークではありません。

C ++標準ライブラリから98話の始まりははstd :: auto_ptrはスマートポインタの提供を開始しましたが、C ++でのstd :: auto_ptrを11に破棄されます。C ++ 11の標準ライブラリのスマートポインタは、より良い導入しました。std :: shared_ptrのとstd :: weak_ptrをブースト:: shared_ptrのブースト:: weak_ptrをのBoost.SmartPointsから。該当するのstd :: unique_ptrを達成を後押ししません。しかし、ライブラリーに追加4つの標準スマートポインタではないBoost.SmartPointersの提供:ブースト:: scope_ptr、ブースト:: scoped_array、ブースト::のshared_arrayとブースト:: intrusive_ptr。

独占所有権

ブーストは、:: scope_ptrは、動的に排他的なスマートポインタオブジェクトを割り当てられています。ブースト:: scope_ptrをコピーまたは譲渡することはできません。スマートポインタは、ヘッダファイルのブースト/ scoped_ptr.hppで定義されています。

例1.1。のブーストを使用する:: scoped_ptrを

#include <boost/scoped_ptr.hpp>
#include <iostream>

int main()
{
  boost::scoped_ptr<int> p{new int{1}};
  std::cout << *p << '\n';
  p.reset(new int{2});
  std::cout << *p.get() << '\n';
  p.reset();
  std::cout << std::boolalpha << static_cast<bool>(p) << '\n';
}

ブースト::スマートポインタのscoped_ptrをタイプは、それが管理オブジェクトの所有権を譲渡することはできません。ブースト::オブジェクトの後にscoped_ptrを初期化アドレスが動的に割り当てられた場合、または破壊scoped_ptrをリセット()メソッドを呼び出すときにリリースされます。

ブースト:: scoped_ptrをを使用Example1.1 スマートポインタpを入力し、デジタルポインタ1によって割り当てられた動的にP点が初期化されます。オペレータにより*、pが1標準出力に間接参照して印刷されます。

新しいアドレスにリセットすることができる()メソッドは、例reset()メソッドで使用される、スマートポインタに格納されているが、p動的2に割り当てられた新しい番号に導入し、元のオブジェクトに格納されているPが自動的に解放されます。

get()メソッドは、スマート裸のアドレスに格納されているオブジェクトへのポインタを返す例えば、リターンアドレス()逆参照を取得し、標準出力に出力得2。

ブースト:: scoped_ptrをオーバーライドブール演算子。オブジェクト参照にスマートポインタが(すなわち、空ではない)が格納されている場合、ブール演算子はtrueを返します。例では、出力標準出力偽のは、P・コール・リセットは、()がクリアされているため。

scoped_ptrをブーストよう::動的に割り当てられたアドレスアレイが初期化されている使用しないscoped_ptrを、ブースト::デストラクタリリースはそれを削除使用してオブジェクトを指すが、動的に割り当てられた配列を解放するために[]削除する必要があります。配列の場合、Boost.SmartPointersはブースト:: scoped_arrayクラスを提供します。

例1.2。使用ブースト:: scoped_array

#include <boost/scoped_array.hpp>

int main()
{
  boost::scoped_array<int> p{new int[2]};
  *p.get() = 1;
  p[1] = 2;
  p.reset(new int[3]);
}

スマートポインタブースト:: scoped_arrayと同様の方法を用いてブースト:: scoped_ptrを、主な違いは、ブーストです::それが含まれているオブジェクトを解放するために[]削除デストラクタで使用scoped_array。ブースト:: scoped_arrayが動的に割り当てられへのポインタを初期化するためのポインタの配列を使用しなければならないので、この動作は、アレイにのみ適用可能です。

ブースト:: scoped_array / scoped_array.hppヘッダファイルブーストで定義されました。

ブースト:: scoped_arrayオーバーロード演算子[]は、要素[]配列アクセス演算子を指定するために使用されてもよいです。ポインタの配列のその保全と同様の挙動のブースト:: scoped_arrayオブジェクトタイプので。例1.2 Pは、数2が格納されている二番目の配列要素に格納されています。

そして、メンバ関数のgetのようなブースト:: scoped_ptrを()生のポインタを取得するために使用することができ、RESETは()に含まれるオブジェクトをリセットするために使用することができます。

共有所有権

スマートポインタブースト:: shared_ptrのブースト:: scoped_ptrを同様に、主な違いは、ブーストです:: shared_ptrのは、必ずしもオブジェクトの唯一の所有者ではありません。所有権は、ブースト:: shared_ptrのスマートポインタの他のタイプで共有することができます。この場合、唯一の最後の共有ポインタでそれを参照することで共有される動的オブジェクトは、唯一のライフサイクルの終了後にリリースされます。スマートポインタをコピーすることができますので、ブースト:: shared_ptrの缶株式所有するので、ブーストのために:: scoped_ptrをすることは不可能です。

ブースト::ヘッダファイルで定義されたブーストのshared_ptr / shared_ptr.hpp。

Example1.3。ブーストを使用する:: shared_ptrの

#include <boost/shared_ptr.hpp>
#include <iostream>

int main()
{
  boost::shared_ptr<int> p1{new int{1}};
  std::cout << *p1 << '\n';
  boost::shared_ptr<int> p2{p1};
  p1.reset(new int{2});
  std::cout << *p1.get() << '\n';
  p1.reset();
  std::cout << std::boolalpha << static_cast<bool>(p2) << '\n';
}

例1.3用途ブーストの2種類:: shared_ptrのスマートポインタP1とP2、初期化するのP2 P1使用、手段、int型のオブジェクトの2つのスマートポインタの株式所有という。P1コールリセット()メソッド、オブジェクトの新しいタイプはint型P1にバインドされているが、これは、オブジェクトが、オブジェクトので、P2で開催されているので、元のint型のオブジェクトが破壊されることはありません。まだ存在しています。所有者のみのリセット()p1が物体2のint型であり、後に呼び出され、P2は、オブジェクトの唯一の所有者は、int型1です。

ブースト:: shared_ptrの内部参照カウント。唯一のブーストで:: shared_ptrのは、オブジェクトが解放されます削除し、のみ、動的オブジェクトの参照ポインタが破壊された後、最後に検出されました。

そして、ブースト:: scoped_ptrを同様に、ブースト:: shared_ptrの過負荷BOOL()演算子、およびオペレータ* - >演算子。また、メンバ関数は、新しいオブジェクトを結合するために、生のポインタリセット()関数を取得するために()を取得提供します。

ブースト:: shared_ptrのは、2番目のパラメータとして削除されたの建設に渡すことができます。これは、関数またはオブジェクトを削除する機能もあり、インスタンス化されたブーストを受け入れる:: shared_ptrのが唯一のパラメータである必要があります。ブースト:: shared_ptrのデストラクタが、削除すると削除されたデバイスは、置換と呼ばれています。この機能は、ブースト:: shared_ptrの他のリソース・マネージャーが動的に割り当てられたオブジェクトの外に使用することができることができます。

例1.4。ブースト:: shared_ptrのカスタム削除手段

#include <boost/shared_ptr.hpp>
#include <Windows.h>

int main()
{
  boost::shared_ptr<void> handle(OpenProcess(PROCESS_SET_INFORMATION, FALSE,
    GetCurrentProcessId()), CloseHandle);
}

実施形態1.4ボイドインスタンス化ブースト:: shared_ptrので。OpenProcess()は、結果は最初のパラメータとしてコンストラクタに渡され戻ります。OpenProcess()は、Windowsの機能は、取得プロセスを処理しています。一例では、OpenProcess()は、例えばそれ自体が現在のプロセス・ハンドルへのポインタを返します。

Windowsは、参照リソースへのハンドルを使用します。リソースが不要になった場合、ハンドルが近いCloseHandleを()を使用する必要があります。CloseHandleを()は、閉じたハンドルで唯一のパラメータです。一例では、CloseHandleを()はコンストラクタブーストの2番目の引数として渡さ:: shared_ptrの、すなわちCloseHandleを()をハンドル削除手段です。場合関数は終了メインハンドル()が破棄されると、スマートポインタのデストラクタは、(CloseHandleをを呼び出して)スマートポインタを閉じるために、最初のパラメータとしてコンストラクタハンドルに渡されます。

注:Windowsのハンドルが無効と定義されますので、例1.4は正常に動作しているタイプ。OpenProcess()voidを返していない場合は、値型またはCloseHandleを()は型がvoid *のパラメータを受け付けない、ブースト:: shared_ptrのは、この例で使用することはできません。ブーストをしない削除::すべてのリソースを管理するための汎用ツールとなっshared_ptrの。

例1.5。使用ブースト:: make_shared

#include <boost/make_shared.hpp>
#include <typeinfo>
#include <iostream>

int main()
{
  auto p1 = boost::make_shared<int>(1);
  std::cout << typeid(p1).name() << '\n';
  auto p2 = boost::make_shared<int[]>(10);
  std::cout << typeid(p2).name() << '\n';
}

Boost.SmartPointersツールは、ブースト機能を提供:: make_shared()でブースト/ make_shared.hppに。ブースト:: make_shared()を使用すると、直接ブースト:: shared_ptrのスマートポインタ型を作成するために、ブースト:: shared_ptrののコンストラクタを呼び出すことはできません。

ブーストを使用することの利点:: make_shared()オブジェクトによって使用される保存と一緒に格納することができるスマート・ポインタのメモリ参照カウンタ内部ダイナミックメモリを節約することです。ブースト:: make_shared()動的オブジェクトを作成し、ブーストのコンストラクタに新しいカウンタのより効率的な使用を作成するために、新たな参照を使用する最初のよりを使用して:: shared_ptrの。

配列はまた、ブースト:: make_shared()を使用することができます。実施形態では1.5、第2の呼を後押しする:: make_shared 10素子P2の配列を結合に。

ブースト:: shared_ptrのバージョン1.53.0スタートからは、アレイをサポートするために始めました。ブースト:: scoped_ptrを関係やブーストなどの::ブースト、などのscoped_array ::のshared_arrayは、スマートポインタブースト:: shared_ptrのに似ています。Boost1.53.0のVisual C ++ 2013以降であれば、その後のビルドに、例えば、P2タイプのための1.5には、クラスのブーストを出力します:: shared_ptrの<整数[0]>。

スタートからBoost1.53.0バージョン、ブースト:: shared_ptrのは、単一のオブジェクトと配列の両方をサポートし、自動的にリソースを解放するために、[]削除するか、または削除を使用する必要性を検出します。ブースト:: shared_ptrのもオーバーロード演算子[](バージョン1.53.0)ので、ブーストの使用に代わる::のshared_arrayとして使用することができます。

特別なスマートポインタ

これまでに導入された各スマートポインタは、さまざまなシナリオで独立して使用することができます。しかし、ブースト::弱い:: ptrが唯一のブーストで使用する:: shared_ptrのは内にあり、理にかなっています。ブースト::でブースト/ weak_ptr.hppで定義されてweak_ptrを。

例1.8。のブーストを使用する:: weak_ptrを

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <thread>
#include <functional>
#include <iostream>

void reset(boost::shared_ptr<int> &sh)
{
  sh.reset();
}

void print(boost::weak_ptr<int> &w)
{
  boost::shared_ptr<int> sh = w.lock();
  if (sh)
    std::cout << *sh << '\n';
}

int main()
{
  boost::shared_ptr<int> sh{new int{99}};
  boost::weak_ptr<int> w{sh};
  std::thread t1{reset, std::ref(sh)};
  std::thread t2{print, std::ref(w)};
  t1.join();
  t2.join();
}

ブースト::弱い:: ptrがブースト:: shared_ptrのを初期化する必要があります。その最も重要な機能は、ロックのメンバーです()。ロック()は、弱いポインタの入ってくる共有ポインタの共有所有権はブースト:: shared_ptrのを初期化し返します。共有ポインタが空の場合、返されたポインタは空になります。

次のようにブースト::のweak_ptrシーンを使用することができます:ポインタ管理オブジェクトを使用する必要が共有する機能が、オブジェクトのライフサイクルは、関数自体に依存してはならないとき。プログラムは、オブジェクトポインタの共有所有権は、少なくともどこか別の場所がある場合にのみ、この関数は、オブジェクトを使用することができます。このポインタは場合、共有、および管理対象オブジェクトが追加の共有ポインタを存在し、生き残る機能によるものではないことをリセットしそうです。

二つの主要な機能の例1.8は、スレッドを作成し、最初のスレッド)(引数として共有参照ポインタを受信し、スレッドにリセットを呼び出します。第二のスレッドがパラメータとして弱いポインタ参照を受信し、スレッドが印刷()を呼び出します。以前に初期化され、上述したポインタと共有弱いポインタ。

同じプログラムが実行を開始したときに実行時間、リセット()および印刷()が、その実行順序では不明です。このポーズは、印刷中に潜在的な問題()が呼び出され、オブジェクトがちょうど(リセットされた)破壊されました。

弱いポインタは、この問題を解決することができます:あなたはロック(呼び出したとき)、オブジェクトがまだ生きている場合は、次の利用可能な共有のポインタリターンを。オブジェクトが破棄された場合、返された共有ポインタは0に設定され、ヌル・ポインタと同等です。

ブースト::弱い:: ptrは、それ自体は、オブジェクトのライフサイクルに影響を与えることはありません。プリントで安全に()にアクセスする関数オブジェクト、ロック()にブースト:: shared_ptrのを返します。別のスレッドがオブジェクトを解放しようとしても、オブジェクトが原因で生き残るためには、この共有ポインタを返されることをこれが保証されます。

おすすめ

転載: www.cnblogs.com/caiminfeng/p/11911813.html