shared_ptrの使用
メモリを割り当て
- make_shared
//make_shared<int>分配一块int类型大小的内存,并值初始化为100
//返回值是shared_ptr类型,因此可以直接赋值给sp
shared_ptr<int> sp = make_shared<int>(100);
-
新しい
我々は暗黙のうちにスマートポインタに組み込まれたポインタは直接の形で初期化されなければならないことができるように、明示的なポインタインジケータのパラメータのコンストラクタを受け入れるのみ
//错误! 不会进行隐式转换,类型不符合
shared_ptr<int> sp1 = new int(100); //正确,直接初始化调用构造函数 shared_ptr<int> sp2(new int(100000));
shared_ptrの操作
まあ割り当てられたメモリ空間が、我々は動作のshared_ptrの定義を使用することができます
-
p.get()が
格納されたポインタPを返します -
スワップ(P、Q)
のスイッチングのp、qが記憶されているポインタ -
shared_ptrの< T > P(Q)
Pは、Qのコピーであり、それらは相互に、同じメモリを指し -
P = Q
pとqが割り当てられると、次にP、同じメモリへのQ点、基準カウントQ + 1、P(元のメモリ空間)参照カウント-1 -
p.use_count()
スマートポインタPと共有オブジェクトの数を返します -
shared_ptrの< T > P(Q、D)
Q T *はポインタに変換することができるされ、Dは、代わりにメモリを解放する、リファレントP qの所有権を引き継ぐために呼び出し可能なオブジェクト(削除される)、であるデリータdを削除 -
p.reset()は
ヌルポインタPにリセットされます -
p.reset(P)
のP-Pリセット(値) -
p.reset(P、D)
P-リセットP(値)およびd削除手段として
独立性に関連したshared_ptrの
もっと共有ポインタが同じスペースを指し、それらの関係を関連付けることができる(私たちは正常な関係を期待して)、または独立した(偽の状態)
shared_ptr<int> sp1(new int(10)); shared_ptr<int> sp2(sp1), sp3; sp3 = sp1; //一个典型的错误用法 shared_ptr<int> sp4(sp1.get()); cout << sp1.use_count() << " " << sp2.use_count() << " " << sp3.use_count() << " " << sp4.use_count() << endl; //输出 3 3 3 1
SP1、SP2、SP3は、それが関連付けられたメモリを解放するために彼らの参照カウントによってSP1、SP2、SP3の独立した、SP4であるにもかかわらずポインタが、同じメモリに、SP4ポイントをメモリの寿命の意味における共同支配を相互に共有されています。
のみであっても、各のshared_ptrのアドレス値と直接関連したこれらの共有ポインタ前のshared_ptrのshared_ptrを持つ別の割り当ては、自立につながります。
削除のshared_ptrにフィルタを渡します
デフォルトのshared_ptrの利用は空きメモリに削除して、デストラクタを実行するため、2例以上は適用されないために我々が持っているので、時には我々は、非新しいオブジェクトを管理するスマートポインタを使用する必要がある、またはクラスのデストラクタではありません速達が削除されます
型T *の単一のパラメータを受け入れる必要があります削除、
//没有析构函数的类
struct MyStruct
{
int *p;
MyStruct():p(new int(10)) { } //构造函数中申请了一块内存 //用裸指针管理,不用时需要手动释放 }; void main() { //st是局部的对象,存放在栈区 //并非由new申请,不可用delete释放内存 MyStruct st; //一个作用域 { shared_ptr<MyStruct> sp(&st, [](MyStruct *ptr) { delete(ptr->p); ptr->p = nullptr; cout << "destructed." << endl; }); } // 离开作用域,调用传递的删除器释放sp所指的内存空间 }
上記の例では、第1の部分のオブジェクトを解放するために使用されず削除して空き領域のアプリケーションへのデストラクタを体mystructない、削除はそのshared_ptrのを管理するための2つのことを行う渡されます。
shared_ptrの罠
別々のshared_ptrを書いてはいけません
上記の意味とのshared_ptrの独立性の危険性が言わなければならない、このエラーを回避するために、次のことを守っ
- 素手で混ぜて使用しないでください
//错误场景1
int *x(new int(10)); shared_ptr<int> sp1(x); shared_ptr<int> sp2(x); //虽然sp1、sp2都指向x所指的内存,但他们是独立的, //会在其他shared_ptr还在使用内存的情况下就释放掉内存 //失去了设计共享指针的意义 //同时,使用裸指针x本身也是很危险的,x随时可能变成空悬指针而无从知晓
//错误场景2
//函数接受一个共享指针参数
void func(shared_ptr<int> sp); int *x(new int(10)); //创建了一个指向x指针所指内存的共享指针,引用计数为1,是引用这块内存的唯一共享指针 func(shared_ptr<int> (x)); //离开函数即离开共享指针的作用域,这块内存即被删除
- p.get()の戻り値が割り当てられたのshared_ptrを使用しないでください
shared_ptr<int> sp1(new int(10));
//sp2与sp1独立 shared_ptr<int> sp2(sp1.get()),sp3; //sp3与sp1独立 sp.reset(sp1.get());
使用注意p.get()の戻り値
p.get()戻り値は、裸のポインタの値に相当し、この値の不適切な使用は、上記のエラートラップの全ては、以下の規則に準拠し、発生する可能性
-
p.get保存()の戻り値はいけない
、間違っているかであるshared_ptrの生のポインタとして格納されているかどうか
、それは空いているポインタになります時に生のポインタが分からないとして保存を
別々のポインタが生成されるのshared_ptrとして保存されます -
削除p.get()の戻り値はしないでください
倍のメモリのブロックを削除するには、エラーが発生します
shared_ptrのに渡され、削除することを忘れないでください
非のshared_ptrの管理、あるいは全くクラスのデストラクタを持つ新しいオブジェクトが配信削除手段のために適したものでなければならない場合