スマートポインタは---ライブラリで提供さboost.smart_ptrを後押し

すべての側面からブースト申し出scoped_ptrを、scoped_array、shared_ptrの、のshared_array、weak_ptrを、instrusive_ptrを含む6つのスマートポインタは、STD :: auto_ptrは、異常セキュリティを強化します。ライブラリー内の2つのクラス--Shared_ptrと新しい標準C ++ TR1ライブラリへのweak_ptrの収入となっています。

これらのスマートポインタはsmart_ptrセットを使用するために、あなたはヘッダファイルをインクルードする必要があり、名前空間boost内にあります

#include<boost/smart_ptr.hpp>
using namespace boost;

1.scoped_ptr

scoped_ptrを動的に新しいオペレータは、ヒープ上に割り当てられたオブジェクトを動的に作成されたオブジェクトが適切にいつでも取り外すことができることを確認するためにラップ非常に類似auto_ptrはスマートポインタです。しかし、所有権scoped_ptrをより厳格には、非譲渡、scoped_ptrを得れば、オブジェクトの管理上、あなたが戻ってそこからそれを得ることができなくなります。
scoped_ptrを良い名前を持っている、それは読者のコードに明確なメッセージを伝える:スマートポインタは再びこのの範囲内でのみ使用することができ、転送する必要はありません。
1.1使用
scoped_ptrをの使用は非常に簡単です:ポインタ変数を使用して、新しいローカル使用scoped_ptrをオブジェクトの式の結果を受け入れなければならなかったし、それにそれらの余分のtry / catchおよび削除操作を取り除きます。このように:

scoped_ptr<string> sp(new string("text"));

scoped_ptrは、その動作は、実質的に通常のスマートポインタと同じであるので、「スマートポインタ」である*使用し、非常に精通することができます - >演算子:

cout<<*sp<<endl;//取字符串的内容
cout<<sp->size()<<endl;//取字符串的长度

しかし、覚えていない:操作を削除することはもはや必要性を、scoped_ptrを、自動的に、我々は削除scoped_ptrをに実行した場合、コンパイラエラーになります、私たちがリソースを解放するのに役立ちますscoped_ptrをの行動と同様のポインタオブジェクトではなく、オブジェクトの削除アプリケーションへのポインタであるため、これは許可されていません。
1.2とauto_ptrは違い:
(auto_ptrは経営権を失っている間)はほぼ同じでscoped_ptrを使用量のauto_ptr、それは別のauto_ptrに置き換えることができ、ほとんどのケースでは、それはまた1からポインタauto_ptrは経営権を取得することができます。
、その意味のauto_ptrに移転、scoped_ptrを代入をコピーすることができないため、コンテナの要素型の要件を満たしていないです:コンテナ要素を使用することはできませんが、さまざまな理由で- scoped_ptrをも同じ欠点のauto_ptrにしています。
その所有権のauto_ptrポインタの根本的な違いがscoped_ptrを。auto_ptrは、特別ポインタの転送所有権にのみポインタ管理auto_ptrは同時に、機能の間を通過するように設計されています。scoped_ptrをコピーコンストラクタと代入機能は、ポインタの移動所有権を拒否し、プライベートに宣言されている-あなた自身をscoped_ptrをするだけで、誰もポインタの絶対的な安全性を確保するように、管理ポインタにアクセスする権利を持っていません。

2.scoped_array:

scoped_array scoped_ptrをヒープ上に割り当てられたダイナミックアレイに新しい[]演算子(単純新しいず)をラップれる、など、正しくメモリを解放を保証するために、ダイナミックアレイための薬剤が提供されます。
scoped_arrayスマートポインタの欠陥の配列を指していない標準ライブラリを構成しています。
scoped_arrayインタフェースと機能はほぼ同じ(またはそれ以下)をscoped_ptrを以下のように、主な特徴は:
-コンストラクタは、新しい表現の結果、新たなポインタP []結果を受け入れ、かつてはならない;
-なし- *それが保持されている通常のポインタscoped_arrayないので、オーバーロード>オペレータ;
-デストラクタを削除使用して[]なく削除よりも、リソースを解放する;
-提供演算子[]演算子オーバーロード以下の表アクセス要素によって表されるように、通常の配列のようにすることができ;
- イテレータ操作機能が開始()、終了()と同様のコンテナではありません。
2.1使用方法:
scoped_arrayと同じデザインからscoped_ptrを、従って使用は、それのみ、割り当てをコピーすることができない、宣言されたアクションの範囲内で使用することができ、非常に類似しています。唯一の違いは、パッケージングは、ポインタが新しいscoped_array []が生成されていることであり、それはダイナミックアレイではなく、単一の移動オブジェクトによって管理されるので、デストラクタの呼び出しは、] [削除します。

このようなものを作成するための通常の方法をScoped_array:

scoped_array sa(new int[100]);//包装动态数组

それは規則的なアレイのようなアップ使用されるように、オーバーロード演算子[] scoped_array、それはポインタ演算を提供していないので、アクセス・アレイの要素に「アレイ先頭アドレス+ N」が使用されません。

sa[0]=10;//正确用法,使用operator[]
*(sa+1)=20;//错误用法,不能通过编译

注意するオーバーロード演算子を使用する際には、[]、scoped_arrayは、配列のインデックスをチェックする範囲を提供していないときは、動的配列の大きさよりもインデックス以上を使用する場合は、負のインデックスは、未定義の動作につながります。
2.2推奨:
プログラムには、追加負担は使いやすい、軽量ではありませんscoped_array。元の配列の速さでその速度は、それはプログラマのヒープメモリ上に割り当てられnew演算子を使用して慣れている人たちに適しています。scoped_array機能は非常に限られているし、動的に成長することはできません。しかし、イテレータのサポートはSTLアルゴリズム、唯一の純粋な「裸の」配列インタフェースで、そこではありません。ので、我々は新しい[]演算子を使用しないようにしてください、それは、エラーの新しい、多くの供給源よりもひどいです

int *p = new int[10];
delete p;

コンパイラまたはプログラマのいずれかをコンパイルすることができ、このようなコードは、新しいと新しい[]割り当てられたスペースを区別し、例外が発生します資源の誤った使用を削除することは非常に困難です。

必要な場合には、我々はscoped_arrayより多くの柔軟性を提供しますが、唯一の賃金に小さな代償を払ったのstd ::ベクトルの動的配列を使用する必要があります。

そこにパフォーマンスのための非常に厳しい要件である、またはそれだけで使用する古いCスタイルのコードとの互換性のためだと同様に、コンパイラは、それ以外の場合は推奨されませんscoped_array、標準ライブラリをサポートしていない場合を除き、それはあなたのコードは、危険が隠されていることが多いの手段を表示されます。

3.shared_ptr:

スマートポインタを含めても、いくつかの他の領域を使用している - のshared_ptrはboost.smart_ptrライブラリは、最も重要な部分は、最も有用な、多くのライブラリーの形成を後​​押ししている、最も価値がある、最重要指名手配スマートポインタのポインタでありますshared_ptrの。

shared_ptrのscoped_ptrを包装およびヒープ上に割り当てられた新たなオペレータ動的オブジェクトとして、それが達成される参照カウントスマートポインタが自由にコピーされ、任意の場所でそれをシェアを割り当てられ、コードが使用されていない場合にすることができる(参照カウントは、それが動的時にラップされたオブジェクトに割り当てられた削除)はゼロです。shared_ptrの基準は、安全なコンテナに入れ、作るとSTLコンテナ要素の欠乏などのauto_ptrポインタので、可能な移動の意味ではないことがあります。

3.1使用法:
それはauto_ptrをしてscoped_ptrをの適用範囲よりも広いので、知的な行動のshared_ptrが、その元のポインタに最も近います。ほぼ100%の新しい結果の動的割り当てを受け入れることができ、シンプルでauto_ptrをとscoped_ptrをとしてどこでも新しい、次いで任意完全に利用し、削除メモリリークを排除するための使用、及びその使用現れます。

shared_ptrのは、基本的なスレッドの安全性の保証を提供し、安全なshared_ptrのは、複数のスレッドで読み取ることができますが、アクセス結果の他の形態は不定です。
これは、標準コンテナを適用:
適用(他の容器またはアダプタなど)標準コンテナをshared_ptrのための2つの方法があります。
1)、オブジェクトのshared_ptr管理などの容器、などはshared_ptr<list<T> >、コンテナを安全に共有することができる使用し、一般的なshared_ptrの差がない;
例えば2)、コンテナ要素としてのshared_ptr、vector<shared_ptr<T> >shared_ptrの支持体としては、複雑な意味論と比較動作、コピーポインタは、セキュリティコンテナエレメントを受信する代わりに、コピーで実現することができるようにコンテナ要素のための標準的な要件。
標準コンテナのauto_ptrは、特にC ++標準所定の時間に対応することはできません。scoped_ptrを標準コンテナを収容することができない、とscoped_ptrを割り当てているためコピーできません。標準コンテナは、元のポインタに対応するが、コンテナの多くの利点が失われ、標準コンテナが自動的にポインタ型の要素を管理することはできませんので、あなたはポインタの多数が最終的に正しく削除されることを保証するために、追加のコードを記述する必要があり、トラブルを達成するために、通常は非常に困難であることができます。

コンテナと元の関数ポインタストレージのshared_ptrはほぼ同じですが、プログラマのためのshared_ptrのポインタは、管理作業を行うために格納するコンテナは、あなたが任意のリソース・リークの恐れなしのshared_ptrを使用することができます。

4.shared_array:

類似のshared_ptrをのshared_array、それが解放後には参照が存在しないまでも、プログラムのライフサイクルにおいて、参照カウントメカニズムが動的配列のプロキシを提供し、長期的なプレゼンスを使用し、ヒープ上に割り当てられたダイナミックアレイにおける新[]演算子をラップメモリ。
shared_arrayインタフェースと機能がほとんどのshared_ptr同じであり、主な違いは次の通りである:
-コンストラクタはポインタPが新しい[]の結果、新たな表現のない結果でなければならない受け入れ;
-演算子[]演算子のオーバーロードを提供するようにすることができ同表における配列アクセスと共通の要素;
- * NO - >演算子オーバーロード、以降ではないポインタを保持通常のshared_array;
-デストラクタ削除を使用して、[]はなく削除よりも、リソースを解放します。
4.1使用方法:

shared_arrayのshared_ptrとscoped_array組み合わせのように - すなわちshared_ptrのもscoped_array欠点の利点があります。

#include<boost/smart_ptr.hpp>
using namespace boost;
int main()
{
    int *p = new int[100];
    shared_array<int> sa(p);//shared_array代理动态数组
    shared_array<int> sa2=sa;//共享数组,引用计数增加

    sa[0]=10;//可以使用operator[]访问元素
    assert(sa2[0]==10);
}//离开作用于,自动删除动态数组

インデックスが負であるか、またはダイナミックアレイインデックスのサイズが未定義の動作につながる超える場合のshared_arrayは、範囲チェック配列インデックスを提供していない場合には、同様に、過負荷のshared_arrayオペレータの使用は、[注意してください]。

shared_array制限容量は、ほとんどのケースで使用することができshared_ptr<std::vector>、またはstd::vector<shared_ptr>の代わりに、2つのプログラムがより高いセキュリティと柔軟性を持っていますが、支払った価格はほとんど無視できます。

5.weak_ptr:

weak_ptrを導入するshared_ptrスマートポインタラインである、それは普通のポインタの動作を持っていない、と演算子をオーバーライドしていないので、それは*、より多くのアシスタントではなく、shared_ptrのスマートポインタのようなものです- >、その最大の役割は支援することです観客などのリソースの観測された使用などshared_ptrの仕事、。
5.1使用方法:

web_ptrは、リソースを取得する権利を観測、のshared_ptrのweak_ptrまたは別のオブジェクトの構築から、shared_ptrので動作するように設計されています。weak_ptrをしかし、無共有リソースは、その構造が増加ポインタの参照カウントが発生することはありません。weak_ptrをデストラクタは、参照カウントの減少が発生しない場合も、それは静かにのみ、観客です。

weak_ptrをし、*演算子をオーバーロードしない-それは、共有ポインタが、それは「弱い」は何かということですリソースを操作することはできませんしていないため、意図的である理由>、。しかし、このようにリソースを操作し、shared_ptrのが観察されるのshared_ptrから入手可能オブジェクトを取得するためにメンバ関数ロック()を使用することが非常に重要になることがあります。しかし、機能的等価物は、()==真(期限切れ(期限切れ ) はuse_count関数を()== 0、観察されたリソースがshared_ptrの資源によって管理されていることを示し.use_count不在()関数となっているリソースの観察を参照するために使用されていますヌルポインタのshared_ptrに格納されている)、ロック()関数の戻りを数えます。
shared_ptrでこれを取得します。

重要使用webak_ptrこのポインタのshared_ptrを取得することで、オブジェクト自体が自分自身を管理するためのshared_ptrを生成することができ、あなたは(ロックを呼び出すために必要がある場合ポインタで、このオブジェクトを観察するのweak_ptr、これは、参照カウントに影響を与えません)関数は、コンプライアンスを返します。外での使用のためのshared_ptr。

このソリューションは、イディオムとして実装ヘッダファイルにされた<boost/enable_shared_from_this.hpp>ヘルパークラスを定義しenable_shared_from_this<T>、そのように要約文は次のとおりです。

template<class T>
    class enable_shared_from_this
    {
        public:
            shared_ptr<T> shared_from_this();
    }

ただ、時間の使用は、それを継承することができますshared_ptrのクラスによって管理されるようにしたい作り、メンバー関数shared_from_this()このshared_ptrを返します。例えば:

#include<boost/enable_shared_from_this.hpp>     
#include<boost/make_shared.hpp>
class self_shared:public enable_shared_from_this<self_shared>//一个需要用shared_ptr自我管理的类
{
    public:
        self_shared(int n):x(n){}
        int x;
        void print(){
        cout<<"self_shared:"<<x<<endl;
        }
};

int main()
{
    shared_ptr<self_shared> sp = make_shared<self_shared>(314);
    sp->print();

    shared_ptr<self_shared> p = sp->shared_from_this();
    p->x=1000;
    p->print();
}

例えば、通常のオブジェクト(非shared_ptrの)()からのshared_ptr使用shared_from_thisを得ることはありません注:

self_shared ss;
shared_ptr<self_shared> p = ss.shared_from_this();//错误

これは、コンパイラ問題なし構文的に正しいのですが、実行時にshared_ptrのデストラクタスタック上に割り当てられたオブジェクトを削除しようとする試みにつながりますが、未定義の動作が発生します。

6.intrusive_ptr:

intrusive_ptrは、次の2つの状況で使用することができる侵襲型ポインタ参照カウントです。

  • メモリは、元のポインタと同じでなければならない非常に厳しい要求によって占め;
  • 既存のコード、既に参照されたオブジェクトのカウント機構管理。
    shared_ptrのは非常に強力で柔軟なされているので、Boostライブラリは、intrusive_ptr推奨されていない、ほとんどのニーズを満たすために十分な作業。
公開された46元の記事 ウォン称賛13 ビュー60000 +

おすすめ

転載: blog.csdn.net/luliuliu1234/article/details/80471258