std::unique_ptr<T>は、このスマートポインタがただ1つのデータを指していることを保証するために、このインスタンス自体をコピーできないようになっています。所有権を持つといいます。
コード:
std::unique_ptr<int> sp = std::make_unique<int>(0);
std::unique_ptr<int> another_sp = sp; // error!
ただし、所有権はほかのスマートポインタに移動できます。所有権を移動するためには、右辺値にキャスト、専用のヘルパー関数を使えばmoveすることで実現します。
コード:
std::unique_ptr<int> sp = std::make_unique<int>(0);
std::unique_ptr<int> another_sp = std::move(sp); // move
このばあい、もとの「sp」は内部のポインタがnullptrになって使えなくなっています。(これが従来のconst左辺値参照だと、spがconstで変更できないのですが、右辺値参照だと変更できるので実現できます。)
つまり、「spを捨てて、another_spに移動」します。
もしもある関数void func(int*)があったとして、ポインタを渡すときは、
「(同じスレッドで)その関数がそのポインタを別のどこかに記録などして使い回さない」と分かっているときはsp.get()などとしてポインタを渡しても大丈夫です。
そうでないならshared_ptrを渡します。
unique_ptrが普通のポインタと同等に高速ですが、shared_ptrはリファレンスカウンタも余分に確保する分、遅くなっています。
複数のクラスでデータを共有せざるを得ない場合、shared_ptrを使い、そうでないならunique_ptrを使いましょう。weak_ptrはshared_ptrを使ったときに必要になるケースがあります。
(参考 :
http://qiita.com/MasayaMizuhara/items/0 ... aa6d17bb66)
優先順位としてはこうでしょう :
1. そもそもnewしない。 (A a)
2. 何らかのコンテナを使う。 (std::vector<A> a_list)
3. std::unique_ptrを使う。
4. std::shared_ptr/std::weak_ptrを使う。
5. Aを管理するクラスを作って1~4を使う。(class AManager { ... [中にstd::vector<A>, std::unqiue_ptrなど] ... }
6. Aを管理するクラスを作る。(newを使用。ただしコンストラクタでnewしてデストラクタでdeleteすることを守る。)
ちなみに、1つだけのインスタンスが作られると分かっていて、コンストラクタでインスタンスを生成するのが遅くなるという場合 :
コード:
class C {
public:
C() : a { } {
}
void create() {
// ここでaを作りたい
}
private:
A a;
};
は、Optional (次期C++に入る予定。他にもいろいろ実装されているので参考に自分で作っても良いでしょう。)を使うといいです。
std::optional<A> a;
とメンバに持ち、初期化が必要になったときに
a.emplace( なんとか )
とすれば、ヒープからメモリを確保せずに初期化できて便利です。