来自 UP:HexUp
"30 分でわかる現代 C++ の最も重要な機能の一つ:スマートポインタ"
型宣言#
「右左」ルールに従う
変数名から右に向かって読み、読み終わったら左に向かって読む
括弧を無視せず、階層ごとに読む
一つの階層を抜けた後の外側は、内側の要素の型または内側のポインタの指す先を表す
読み取りの順序は、後者が前者の要素の型を表すことを示す
constなどの宣言も「右左」ルールに従う
ポインタのサイズ#
32 ビットアーキテクチャと 64 ビットアーキテクチャ
メモリの最小単位は 1 バイト(Byte)= 8 ビット
32 ビットプログラムのポインタのサイズは 4 バイト
64 ビットプログラムのポインタのサイズは 8 バイト
ポインタのサイズは本質的にはコンパイラによって決定される
ラムダ式#
別名クロージャ
構造:
[キャプチャ変数](引数リスト) -> 戻り値の型 { 関数本体 }
変数のキャプチャは&
を付けずに値によるキャプチャ、&
を付けると参照によるキャプチャ
[&]
はすべての外部変数を参照によってキャプチャ
[=]
はすべての外部変数を値によってキャプチャ
上記の 2 つは組み合わせることができ、[&,=N]
は変数N
を除いてすべての外部変数を参照によってキャプチャ
生ポインタと動的メモリ割り当て#
new
はメモリを動的に割り当てるために使用されます
delete
は手動で割り当てられたメモリを解放するために使用されます。そうしないと、このメモリは解放されません。new
で割り当てられた領域が配列の場合は、delete[]
を使用する必要があります
スマートポインタは、手動でメモリを管理することによるメモリリークを防ぐために使用されます
shared_ptr#
#include <memory>
が必要で、std
名前空間に属します
初期化:
shared_ptr<int> p {make_shared<int>(100)};
shared_ptr<int> p {new int(100)};
shared_ptr<int> p = make_shared<int>(100);
上記のいくつかの方法は完全に同等です
p.use_count()
は同じオブジェクトを指すポインタの数を返します
p.reset()
はポインタをリセットし、元のオブジェクトを指さなくなります。また、引数を設定して新しいオブジェクトを指すようにすることもできます
あるオブジェクトを指すshared_ptr
の数が 0 になると、そのオブジェクトは自動的に破棄されます
p.get()
は現在のオブジェクトを指す生ポインタを取得します
初期化には以下のような特殊なパラメータ設定もあります:
shared_ptr<FILE> sfp {fp, close_file};
第 2 引数はカスタムの破棄関数です
shared_ptr<Bar> b(f, &(f->b));
第 2 引数はクラスのメンバ変数にアクセスするために使用されます
unique_ptr#
ライブラリの基礎、初期化方法はshared_ptr
と同じです
オブジェクトの所有権を独占し、破棄時にバインドされたオブジェクトを自動的に解放します
p.release()
はオブジェクトの生ポインタを返し、同時に p をnullptr
に設定します
所有権はコピーできませんが、移譲は可能です
unique_ptr<int> p2 {p1.release()}
unique_ptr<int> p2 {move(p1)}
p1 の所有権を p2 に移譲します。上記の 2 つの式は同等です
unique_ptr<int, decltype(&my_dealloc)> cup {my_alloc(100), my_dealloc}
カスタムの破棄関数はより複雑で、<>
内で宣言する必要があります
関数間のパラメータの受け渡しには、*p
を直接使用して値を渡すこともできます。また、p.get()
を使用して生ポインタを渡すこともできます。また、関数のパラメータをunique_ptr<int>&
、つまりunique_ptr
の参照に設定することもできます。さらに、move(p)
を使用してオブジェクトの所有権を変更することもできます(この場合、関数のパラメータはunique_ptr<int>
です)
関数の戻り値には追加の制限はありません。unique_ptr<int>
型の関数の戻り値を直接使用してunique_ptr<int>
を初期化することができます。これは実質的にはmove
を呼び出すことと同じです
weak_ptr#
循環依存の問題を解決することができます
weak_ptr
はshared_ptr
に依存し、shared_ptr
を使用して初期化する必要があります
weak_ptr
はオブジェクトの観察権しか持っておらず、オブジェクトの管理権はありません
wp.lock()
はweak_ptr
が指すリソースが解放されている場合はnullptr
を返します