[C ++ノート] C ++スマートポインター

この記事を読む

1.スマートポインターデザインのアイデア

2.スマートポインターは使いやすい

3.auto_ptrの使用が推奨されないのはなぜですか

4.使用するスマートポインターの選択方法

スマートポインターデザインのアイデア

C / C ++ポインターを使用する場合の一般的なピットに関する前回の記事では、C / C ++でポインターを使用するときに発生する可能性のあるさまざまなピットを要約しました。最も一般的なものは、メモリリークです。次の例を思い出してください。
[C ++ノート] C ++スマートポインター
[C ++ノート] C ++スマートポインター

この例では、例外がスローされるため、deleteステートメントを実行する機会がなく、メモリリークが発生します。もちろん、この数十行のプログラムでは、catchステートメントにdeletetを追加して回避することができます。

しかし、それが数十のWラインを持つエンジニアリングプロジェクトである場合はどうでしょうか。バラバラになると思います!それで、より良い方法はありますか?答えはイエスです。

通常のローカル変数(非静的ローカル変数)の場合、スコープを離れると、オペレーティングシステムが自動的に解放します。また、クラスが解放されると、クラスオブジェクトが自動的に呼び出されることもわかっています。デストラクタ。

そこで、次のように考えました。Test* tが通常のポインタ変数ではなく、クラスオブジェクトであり、動的メモリを解放するステップがクラスのデストラクタに実装されている場合、ポインタ変数がスコープを終了する限り動的メモリを解放する目的を達成するために、デストラクタが呼び出されます。これはスマートポインターのアイデアです。

前の仮定によれば、次のように単純なスマートポインタを実装することは難しくありません。

class SmartPointer 
{
    private:
        Test* ptr;
    public:
        SmartPointer(Test* p) 
        {
         ptr = p;
        }
         ~SmartPointer() //析构函数释放资源
         {
         delete p;
         }
};

したがって、それを使用する方法は、次のように、元のコードに基づいて少し変更する必要があります。

[C ++ノート] C ++スマートポインター

C ++スマートポインターは使いやすい

もちろん、私たちが自分で実装したスマートポインターは、非常に粗雑なスマートポインター設計のアイデアを説明するためのものです。通常の使用では、スマートポインターを自分で定義する必要はありません。C++には、使用できる既製のスマートポインターがすでに用意されています。

C ++ STLは、auto_ptr、unique_ptr、shared_ptr、weak_ptrの4種類のスマートポインターを提供します。そのうち、auto_ptrはC ++ 98によって提供されるため、C ++ 11で破棄することをお勧めします。理由については、後で説明します。unique_ptr、shared_ptrそして、weak_ptrはC ++ 11の登場とともにSTLに追加されました。

以下に示すように、スマートポインタの使用は実際には難しくありません。
[C ++ノート] C ++スマートポインター
[C ++ノート] C ++スマートポインター

auto_ptrの使用が推奨されないのはなぜですか

最初に次のステートメントを見てください。

auto_ptr<int> px(new int(8));
auto_ptr<int> py;
py = px;

上記の割り当てステートメントは何を達成しますか?pxとpyが通常のポインターである場合、2つのポインターは同じ動的に割り当てられたintオブジェクトを指します。プログラムが同じオブジェクトを2回削除しようとする可能性があるため(pxの有効期限が切れたときとpyの有効期限が切れたとき)、これは受け入れられません。同じメモリを2回削除することはできません。この問題を回避するには、主に次の2つの方法があります。

  • 所有権(所有権)の概念を確立します。特定のオブジェクトの場合、同時に所有できるスマートポインターは1つだけです。たとえば、スマートポインターAがオブジェクトxを指している場合、B = Aが実行されると、元のポインターAはxの所有権を失い、オブジェクトのみが所有されます。スマートポインタのコンストラクタはオブジェクトを削除します。unique_ptrとauto_ptrはこの戦略を使用しています。

  • よりスマートなポインターを作成し、特定のオブジェクトを参照するスマートポインターの数を追跡します。これは、参照カウントと呼ばれます。たとえば、値を割り当てると、カウントが1増加し、ポインタが期限切れになると、カウントが1減少します。0に減ると、削除が呼び出されます。これは、shared_ptrによって採用された戦略です。

もちろん、コピーコンストラクターにも同じ戦略を使用する必要があります。

C ++ 11でauto_ptrを破棄することが推奨される理由を見てみましょう。次の例を見てください。
[C ++ノート] C ++スマートポインター
[C ++ノート] C ++スマートポインター
プログラムの実行結果から、割り当てステートメントpy = pxを実行すると、pxにアクセスするとプログラムがクラッシュします。その理由は、割り当てステートメントpy = pxがオブジェクトの所有権をpxからpyに転送し、pxがnullポインターになっているためです。もちろん、pxに再度アクセスするとエラーになります。

では、unique_ptrまたはshared_ptrを使用するとどうなりますか?テストしてみましょう。最初にunique_ptrの状況を見てみましょう。unique_ptr
[C ++ノート] C ++スマートポインター
[C ++ノート] C ++スマートポインター
を使用すると、この場合のコンパイル時にエラーが発生します。つまり、unique_ptrもauto_ptrのような所有権モデルを使用しますが、プログラムはunique_ptrを使用するときに待機しません。実行時にクラッシュし、コンパイル中に潜在的なエラーが発生する可能性があります

さて、shared_ptrの状況を見てみましょう
[C ++ノート] C ++スマートポインター
[C ++ノート] C ++スマートポインター
。shared_ptrは参照カウントを使用するため、shared_ptrを使用すると正常に実行されます。割り当てステートメントpy = pxが実行された後、pxとpyは同じメモリを指しますが、スペースを解放するときは、事前に判断する必要があります。したがって、参照カウント値のサイズによって、オブジェクトを複数回削除するというエラーが発生することはありません。

どのスマートポインタを選択するか

これらのタイプのスマートポインターを理解した後、あなたは自然に質問を考えるかもしれません:実際のプロジェクトアプリケーションでどのスマートポインターを使用すべきですか?これらのスマートポインタの特性に応じて、次の提案があります。

  • プログラム内の同じオブジェクトへの複数のポインターを使用する場合は、shared_ptrを使用する必要があります。たとえば、ポインターを含むSTLコンテナーがあり、コピーおよび割り当て操作をサポートするSTLアルゴリズムを使用して、コンテナーのポインター要素を操作します。 shared_ptrを使用する必要があります。unique_ptr(コンパイラエラー)およびauto_ptr(不確実な動作)は使用できません。

  • プログラムが同じオブジェクトへの複数のポインタを使用する必要がない場合は、unique_ptrを使用できます。関数がnewを使用してメモリを割り当て、メモリへのポインタを返す場合は、その戻りタイプをunique_ptrとして宣言することをお勧めします。このようにして、所有権は戻り値を受け入れるunique_ptrに転送され、スマートポインターがdeleteの呼び出しを担当します。

  • unique_ptrに必要な条件が満たされている場合は、auto_ptrも使用できますが、unique_ptrの方が適しています。

総括する

この記事では、一般的なスマートポインターの基本的な使用法のみを要約し、実際の使用で注目に値する多くのポイントがあります。後の記事では、これらの詳細を要約し続けます。つまり、C ++を学習するプロセスは、ピットを踏むプロセスです。

推奨読書:

[福祉]自分で集めたオンライン品質コースのビデオ共有(
パート1 [プロトコルフォレスト]郵便局と郵便局(ネットワークプロトコルの概要)
[データ構造とアルゴリズム]ビット順序のわかりやすい説明
[C ++メモ] C ++ 11同時プログラミング(1) )スレッドジャーニーを開始する
[C ++ノート] C / C ++ポインターを使用する際の一般的な落とし穴
[C ++ノート]静的および動的ライブラリの詳細な説明(上)

コーディング

コードファーマーには、テクノロジーを簡単にするためのわかりやすい技術記事を提供する正しい方法があります。
[C ++ノート] C ++スマートポインター

サーバーのバックグラウンドテクノロジースタックの知識の概要の共有に焦点を当てる

コミュニケーションと共通の進歩に注意を払うことを歓迎します

おすすめ

転載: blog.51cto.com/15006953/2552128