web-dev-qa-db-ja.com

smart-ptrsに既存の値を割り当てますか?

スマートポインターについて学習しているだけで、既存の変数の場所を標準ライブラリの共有ポインターに割り当てるのに問題があります。

たとえば、値がわからないint xがあるとします。通常のポインターで、私はやった

int* ptr;
ptr = &x;

私は共有ポインターでそれを両方試しました、そして

std::tr1::shared_ptr<int> ptr;
ptr = std::make_shared<int> (&x)

だから私はそれを行う方法についてかなり迷っています。

15
bluepanda

(通常は)スマートポインターが既存の変数を指すようにはしません。スマートポインタは、動的に割り当てられたオブジェクトの有効期間を管理し、使用後に削除します。動的に割り当てられていないものをポイントすると、削除しようとするとエラーが発生します。

通常、newまたはmake_sharedを使用してオブジェクトを作成し、その結果を使用してスマートポインターを作成または割り当てます。

std::shared_ptr<int> ptr(new int(42)); // Create a new pointer to manage an object
ptr.reset(new int(66));                // Reset to manage a different object
ptr = std::make_shared<int>(53);       // Use `make_shared` rather than `new`

make_sharedは通常、newよりも望ましいです。メモリをより有効に利用し、例外の安全性を強化するためです。

25
Mike Seymour

共有ポインタは、動的に割り当てられたメモリを管理するために使用され、より正確には、このメモリの所有権を管理します。

基本的に、スマートポインターは Ressource Acquisition Is Initialization 、またはRAIIの具体化です。リソースの所有権を管理するのに非常に役立つため、この原則を確認することを強くお勧めします(基本的に、メモリ、データベース接続、ファイルハンドラー、ミューテックスなど、リソースを取得して解放する必要があるたびになど)。

それが行うことは基本的に、誰かが管理する動的に割り当てられたメモリを指す間、このメモリが利用可能であり、このメモリへの最後の(スマート)ポインタがスコープから外れるとすぐにdeleteが保証されることです。と呼ばれます。

次に、自動ストレージ期間を持つ変数でスマートポインターを使用することは意味がありません(つまり、スコープから外れたり、メンバーであるオブジェクト自体がスコープから外れたり、削除されたりしたときに削除されます(新しい場合) 'd)。

4
JBL

shared_ptrの参照カウンターがゼロに達するとすぐに、オブジェクトは最後のshared_ptrによって削除されます。スマートポインターを使用すると、そのオブジェクトを削除する関数を指定できます。

deleterは単純な関数(デフォルトは通常のオペレーターの削除)であり、テンプレートパラメーターを介して静的にスマートポインターにバインドする必要があります( unique_ptr を参照) )またはコンストラクターパラメーターを介して動的に( shared_ptr を参照)。

// dynamically via shared_ptr:
//   shared_ptrs share the pointer to the Deleter
//   because they already share a common data structure for reference counting.
auto ignore = [](int* o){
    std::cout<<"i will refuse to delete this object: " << o << "\n";
    std::cout<<"not my responsibility." <<std::endl;
};
std::shared_ptr<int> sptr(&x,ignore);


//statically via unique_ptr:
//  actually, the unique_ptr is as data structure not more than a regular pointer.
//  but a pointer with special copy-constructor and destructor,
//  which will most likely be inlined.
//  there is no space to store a reference to a Deleter dynamically.
struct IgnorantDeleter{
    void operator()(int* o){
        std::cout<<"who ate my cake? " << o << "\n";
        std::cout<<"but i baked it." <<std::endl;
    }
};
std::unique_ptr<int,IgnorantDeleter> uptr(&x);
1
comonad

動的に割り当てられていないオブジェクトを指すスマートポインターを作成しないでください。そうしないと、スマートポインタが割り当てられたメモリを削除しようとする可能性があり、その場合はエラーが発生します。