そろそろC++やります
そろそろC++をやります。そろそろC++をやりたいからです。
何回やるかはわかりません。基礎を理解するまではやろうと思います。
という感じでやっています。
※ 初心者がメモレベルで記録するので、技術記事としてはお力になれないかもしれません。
内容
- 今回は、今まで触れてきたポインタをまとめます。
ポインタ
「ポインター」とも呼びますが、この記事では「ポインタ」の表記を使用します。
アドレス(メモリの位置)を持った変数のことを、ポインタ(またはポインタ変数)と呼びます。
生ポインタとスマートポインタ
C++では、いわゆる一般的なポインタである生ポインタと、リソースの管理を容易にしたスマートポインタが存在します。
生ポインタ
型名 *
を用いて宣言します。
int *intPtr; string *strPtr;
new
などで、メモリを割り当てます。
int *intPtr = new int(123);
ヒープ領域にメモリの確保するので、メモリの解放が必要です。
delete intPtr;
スマートポインタ
スマートポインタは、生ポインタと違いメモリの解放を自動で行ってくれます。スマートポインタは、3種類存在します。
unique_ptr
shared_ptr
weak_ptr
それぞれが別々の特徴を持っているクラスです。
unique_ptr
とshared_ptr
は、ヘルパー関数で初期化します。
auto up = make_unique<int>(234); auto sp = make_shared<string>("Hello World");
weak_ptr
はshared_ptr
から生成します。
weak_ptr wp = sp;
所有権
スマートポインタには、所有権という考えがあります。
所有権を普通のクラスを例にして考えてみます。以下の例では、unknown
という名前のMyClassを、変数mc
とmc2
が参照しています。
class MyClass { public: MyClass(string _name) : name(_name) { } string name; }; int main() { MyClass *mc = new MyClass("unknown"); MyClass *mc2 = mc; return 0; }
この参照を、所有として考えます。
つまり、いくつの変数が所有(参照)しているかです。
unique_ptr
unique_ptr
は、所有権を一つしか持てません。
以下は変数up
に最初に代入して、所有権(参照)はup
が持っています。所有権は一つしかないので、他の変数にも代入するとエラーになります。
auto up = make_unique<int>(124); auto up2 = up; // コンパイルエラー
コードブロックを抜けて使われていないとメモリが解放されます。
shared_ptr
shared_ptr
は、所有権を複数持つことが可能です。
unique_ptr
と異なり、他の変数に代入することができます。
auto up = make_shared<int>(124); auto up2 = up; auto up3 = up; // 実行可能
所有権の数をカウントする、参照カウントが存在します。参照が増えた場合に増やして、コードブロックを抜けると減らします。
auto up = make_shared<int>(124); cout << up.use_count() << endl; // 1 auto up2 = up; cout << up.use_count() << endl; // 2 cout << up2.use_count() << endl; // 2 { auto up3 = up; cout << up.use_count() << endl; // 3 } // コードブロックを抜けるので一つ解放 cout << up.use_count() << endl; // 2
参照カウントが0になった時に、メモリの解放を行います。
weak_ptr
weak_ptr
は弱いため、弱い所有権を持つことしかできません。shared_ptr
から生成できますが、その時に参照カウントは増えません。
auto up = make_shared<int>(124); cout << up.use_count() << endl; // 1 weak_ptr wp = up; cout << up.use_count() << endl; // 1
これは、shared_ptr
を使用して、循環参照が起こってしまう場合に主に使用します。
感想
今まで複数回にわたり触れてきて、これさえ覚えておけば、簡単に使用する分には問題なさそうなところをまとめました。(実戦ではもっと知識が必要そうですが)そこまで複雑ではなさそうというイメージです!
次回から、演算子について1から見ていこうと思います!