そろそろC++やるぞパート16 ポインター ~ スマートポインタ/unique_ptr ~
そろそろC++やります
そろそろC++をやります。そろそろC++をやりたいからです。
何回やるかはわかりません。基礎を理解するまではやろうと思います。
という感じでやっています。
※ 初心者がメモレベルで記録するので、技術記事としてはお力になれないかもしれません。
内容
unique_ptr 宣言
make_unique< >
ヘルパー関数を使用して、unique_ptrの宣言ができます。
unique_ptr<{型}> {変数名} = make_unique<{型}>(<{初期値}>);
int型やstring型の場合はこのように書くことができます。
unique_ptr<int> intSmtPtr = make_unique<int>(2345); unique_ptr<int> intSmtPtr2 = make_unique<int>(); unique_ptr<string> m = make_unique<string>("Hello World!");
また、調べた限りでは、unique_ptrの宣言位は型推論 (auto
)を用いているところが多いようです。
auto intSmtPtr = make_unique<int>(2345); auto m = make_unique<string>("Hello World!");
型推論の詳細はまた後日行いたいと思います。
また、unique_ptrの宣言はmake_unique
ヘルパー関数を使わずに、このように書くこともできます。(参考1、参考2)
unique_ptr<int> intSmtPtr(new int(2345)); unique_ptr<int> intSmtPtr2(new int()); int *x = new int(2453); unique_ptr<int> intSmtPtr3(x);
ですが、C++14 以降ではmake_unique
を使うことが推奨されているらしいです。。(はっきり書かれている場所を見つけられませんでした。)
理由の一つとして、一つの生ポインターを二つのunique_ptrに所有権を渡すことができてしまうためです。
int *x = new int(2453); unique_ptr<int> intSmtPtr3(x); unique_ptr<int> intSmtPtr4(x);
この結果、intSmtPtr4(x);
の宣言は実行できるのですが、スコープからintSmtPtr3
とintSmtPtr4
が共にdelete
されることになった際に、複数回 delete することになり、実行時エラーが生じてしまいます。
自分もmake_unique
などのヘルパー関数を使用する方針にしようと思います。
余談 ----------
余談ですが、「make_unique;提案new_upとしたい」 という記事も見つけて面白いなと思いました。(考え方の一つですが)
簡単にいうと、new
(メモリの割り当てを行う)の行為を行なっているのに、make_unique
にはnewというキーワードが入っていないため変更したいというものでした。
こちらのブログのコードをお借りして、このコードを使用します。
//---------------------------------------- // uniq_ptrの補助 template <typename T, typename... Args> unique_ptr<T> new_up(Args &&...args) { return unique_ptr<T>(new T(std::forward<Args>(args)...)); } template <typename T> using up = unique_ptr<T>; //----------------------------------------
すると、unique_ptr
をこのように宣言することができました。
// 変更前 unique_ptr<int> intSmtPtr = make_unique<int>(2345); auto intSmtPtr2 = make_unique<int>(2345); // 変更後 up<int> intSmtPtr3 = new_up<int>(2345);
こんなことも出来るのかと勉強になりました。
余談終了----------
unique_ptrとは
宣言することは出来ましたが、「これは何?」という話です。
unique_ptrはスマートポインタの中でも、ポインターを共有できないスマートポインタです。
つまり、コピーができません。
生ポインタや他のスマートポインタではコピーができますが、unique_ptrはコピーすることができません。
int *intPtr = new int(1234); // Ok int *intPtr2 = intPtr; unique_ptr<int> intSmtPtr = make_unique<int>(2345); // コンパイルエラー unique_ptr<int> intSmtPtr2 = intSmtPtr;
参考リスト
- 方法: unique_ptr インスタンスを作成して使用する | Microsoft Learn
- unique_ptr - cpprefjp C++日本語リファレンス
- C++ スマートポインタのメモリ管理の仕組み
- c++11;unique_ptrとポリモーフィズム: 万象酔歩
感想
今回は、スマートポインタの一つunique_ptr
を見てみました。まだ一つ目なので、他との比較ができていませんが、「素直なポインタ」という印象です。
次回は、次のshared_ptr
を触ってみたいと思います。