C++とDirectXでゲームを開発していまして、生のポインタを扱うと危険なのが分かって、
スマートポインタを勉強中で直している最中なのですが困ったことがあります。
今現在のソースが、
こんな感じのソースを
これに直しました。
ここで困ったのですが、
みたいに関数に値を渡す際に、ユニークポインタを使っているとうまく値を
渡すことができません。
スマートポインタを使わずに一番上の例みたいに生のポインタだと
上手くいくのですが、スマートポインタを使い関数に値を渡す方法が分からないので教えてください。
C++11 スマートポインタ について
Re: C++11 スマートポインタ について
unique_ptr::getを使用してください。
複数のオブジェクトで共有される可能性のあるポインタ(例えば、リソースなど)には
shared_ptrを用いてください。
複数のオブジェクトで共有される可能性のあるポインタ(例えば、リソースなど)には
shared_ptrを用いてください。
Re: C++11 スマートポインタ について
やりたいことが出来ました!!!ありがとうございます。
unique_ptrとshared_ptrとweek_ptrの使い分けで主に
どういった感じで使い分かればいいのでしょうか?
参考にしていたサイトがunique_ptrを使っていたので、
全部unique_ptrにしていたのですが。。。
unique_ptrとshared_ptrとweek_ptrの使い分けで主に
どういった感じで使い分かればいいのでしょうか?
参考にしていたサイトがunique_ptrを使っていたので、
全部unique_ptrにしていたのですが。。。
Re: C++11 スマートポインタ について
std::unique_ptr<T>は、このスマートポインタがただ1つのデータを指していることを保証するために、このインスタンス自体をコピーできないようになっています。所有権を持つといいます。
ただし、所有権はほかのスマートポインタに移動できます。所有権を移動するためには、右辺値にキャスト、専用のヘルパー関数を使えば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つだけのインスタンスが作られると分かっていて、コンストラクタでインスタンスを生成するのが遅くなるという場合 : は、Optional (次期C++に入る予定。他にもいろいろ実装されているので参考に自分で作っても良いでしょう。)を使うといいです。
std::optional<A> a;
とメンバに持ち、初期化が必要になったときに
a.emplace( なんとか )
とすれば、ヒープからメモリを確保せずに初期化できて便利です。
std::unique_ptr<int> sp = std::make_unique<int>(0);
std::unique_ptr<int> another_sp = sp; // error!
std::unique_ptr<int> sp = std::make_unique<int>(0);
std::unique_ptr<int> another_sp = std::move(sp); // move
つまり、「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つだけのインスタンスが作られると分かっていて、コンストラクタでインスタンスを生成するのが遅くなるという場合 : は、Optional (次期C++に入る予定。他にもいろいろ実装されているので参考に自分で作っても良いでしょう。)を使うといいです。
std::optional<A> a;
とメンバに持ち、初期化が必要になったときに
a.emplace( なんとか )
とすれば、ヒープからメモリを確保せずに初期化できて便利です。
ζ*'ヮ')ζプログラミングはみんなで奏でるシンフォニー