web-dev-qa-db-ja.com

boost :: shared_ptrを既存の変数に作成します

既存の変数があります。

int a = 3;

boost::shared_ptraに作成するにはどうすればよいですか?例えば:

boost::shared_ptr< int > a_ptr = &a; // this doesn't work
27
Bill Cheatham

ただし、既存のポインターから行うには、変数の作成時にマネージポインターに変数を配置する必要があります。

int *a=new int;
boost::shared_ptr<int> a_ptr(a);

それはあなたが間違いなくshared_ptrにスタック変数を入れたくないことを言った悪いことは起こります

何らかの理由で関数がshared_ptrを使用し、スタック変数のみがある場合は、これを実行する方が良いでしょう:

int a=9;
boost::shared_ptr<int> a_ptr=boost::make_shared(a);

こちらをご覧ください:

http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/make_shared.html

また、shared_ptrを使用できる場合は、c ++ 11標準に含まれていることに注意してください。 build talkでHerb Sutterのメモのように、make_sharedと組み合わせてautoを使用できます。

#include <memory>

int a=9;
auto a_ptr=std::make_shared(9);
43
111111

最初に、shared_ptrは、適切なタイプのポインターから自動的に変換されません。あなたがしたいことを明示的に述べなければなりません:

int a = 3;
::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!

ただし、別の問題があります。このコードの効果を想像してください:

int a = 3;
delete &a;

最初に挙げた例では、これはそれほど直接的ではないにしても、必然的に起こります。 shared_ptrが存在する理由は、それへのすべてのポインタが消えたときに物を削除することです。もちろん、これはあらゆる種類の奇妙な動作を引き起こします。

この問題に対処するには2つの方法があります。 1つは、canを削除するものを作成することです。もう1つは、shared_ptrは、それが指すものを実際には削除しません。それぞれに長所と短所があります。

削除できるものを作成する:

長所:

  • シンプルで簡単。
  • オブジェクトの有効期間について心配する必要はありません。

短所:

  • 少し遅いですが、ヒープの割り当てが1つまたは2つ必要になるためです。
  • 結果として shared_ptrはコピーを参照するため、aへの変更は、それが指すものの値に反映されません。

どうやってするの:

::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));

これはかなり似ています(これも動作します)。

::boost::shared_ptr<int> a_ptr(new int(a));

しかし、それはわずかに効率的です。 ::boost::make_sharedは、アロケーターへの呼び出しを節約し、参照の局所性を改善する連続したメモリに参照カウントとオブジェクトを割り当てるための魔法をします。

shared_ptrは、実際にそれが指すものを削除しません:

長所:

  • より高速ですが、まだ参照カウントのヒープ割り当てが含まれています
  • 当面の問題に直接対処します(指しているものは削除できません)。
  • shared_ptraを参照するため、値を変更すると、ポインターを介してアクセスすると、新しい値が表示されます。

短所:

  • shared_ptrは機能します。つまり、コードを読んでいる人も知っている必要があります。
  • あなたが指しているものがすべてのshared_ptrはそれを指し、そうするとそれらのポインタはぶら下がり、それは悪いことです。
  • 前のポイントはこれを非常に危険なソリューションにします。私は一般的にそれを避けます。

どうやってするの:

関数の外のどこか(おそらく匿名の名前空間):

void do_nothing_deleter(int *)
{
    return;
}

そして、関数内で:

int a = 3;
::boost::shared_ptr a_ptr(&a, do_nothing_deleter);
32
Omnifarious

探しているshared_ptrのコンストラクタはexplicitであるため、あなたが書いたものは動作しません。したがって、そのように書く必要があります。

boost::shared_ptr<int> a_ptr(&a); // Don't do that!

thatの問題は、deletea_ptrの保存された値で呼び出されることです。あなたの例ではaには自動保存期間があるため、これは非常に悪いです。したがって、カスタム削除機能も渡します。

boost::shared_ptr<int> a_ptr(&a, noop_deleter);

C++ 11のnoop_deleterの実装:

auto noop_deleter = [](int*) {};

C++ 03バージョン:

// Can't be put in local scope
struct {
    void
    operator()(int*) const
    {}
} noop_deleter;
15
Luc Danton

既存の変数に対してboost :: shared_ptrを作成することはできません。 boost :: shared_ptrに保存されているアイテムは、作成時に保存されます。

ただし、既存の変数のコピーであるboost :: shared_ptrを作成できます。

例えば

int a = 3; // Existing variable
boost::shared_ptr<int> aCopy = boost::make_shared<int>(a); //Create copy with value of a

Make_sharedには<boost/make_shared.hpp>を含める必要があることに注意してください。

8
Lalaland