C++ でスマートポインタを使用する
-
C++ で複数のポインタに
std::shared_ptr
を使用して同じオブジェクトを参照する -
C++ で指定されたオブジェクトを所有するためのポインターに
std::unique_ptr
を使用する
この記事では、C++ でスマートポインターを使用する方法の複数の方法を示します。
C++ で複数のポインタに std::shared_ptr
を使用して同じオブジェクトを参照する
動的メモリの手動管理は、実際のプロジェクトでは非常に困難であり、バグの主な原因であることが多いため、C++ はスマートポインタの概念を個別のライブラリとして提供します。スマートポインタは通常、通常のポインタとして機能し、追加の機能を提供します。その中で最も顕著なのは、ポイントされたオブジェクトを自動的に解放することです。スマートポインタには、shared_ptr
と unique_ptr
の 2つのコアタイプがあります。
次のサンプルコードは、shared_ptr
タイプの使用法を示しています。shared_ptr
は通常、ポイントされたオブジェクトが他の共有ポインタによって参照される必要がある場合に使用されることに注意してください。したがって、shared_ptr
には内部的に関連付けられたカウンターがあります。これは、同じオブジェクトを指すポインターの数を示します。shared_ptr::unique
メンバー関数を使用して、ポインターが現在のオブジェクトを参照する 1つだけであるかどうかを判別できます。関数の戻り型はブール値であり、true
値はオブジェクトの排他的所有権を確認します。reset
組み込み関数は、現在のオブジェクトを最初のパラメーターとして渡されたオブジェクトに置き換えます。オブジェクトを指す最後の shared_ptr
がスコープ外になると、共有オブジェクトは削除されます。
#include <iostream>
#include <memory>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
int main() {
std::shared_ptr<string> p(new string("Arbitrary string"));
std::shared_ptr<string> p2(p);
cout << "p : " << p << endl;
cout << "p2: " << p2 << endl;
if (!p.unique()) {
p.reset(new string(*p));
}
cout << "p : " << p << endl;
*p += " modified";
cout << "*p : " << *p << endl;
cout << "*p2 : " << *p2 << endl;
return EXIT_SUCCESS;
}
出力:
p : 0x2272c20
p2: 0x2272c20
p : 0x2273ca0
*p : Arbitrary string modified
*p2 : Arbitrary string
C++ で指定されたオブジェクトを所有するためのポインターに std::unique_ptr
を使用する
または、C++ は、オブジェクトの唯一の所有者である unique_ptr
タイプを提供します。他の unique_ptr
ポインタはそれを参照できません。unique_ptr
は、通常のコピーおよび割り当て操作をサポートしていません。それでも、オブジェクトの所有権は、組み込み関数 release
と reset
を使用して、2つの unique_ptr
ポインター間で転送できます。release
関数呼び出しは unique_ptr
ポインタを null
にします。unique_ptr
がリリースされると、reset
関数を呼び出して、新しいオブジェクトの所有権を割り当てることができます。
#include <iostream>
#include <memory>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
int main() {
std::unique_ptr<string> p1(new string("Arbitrary string 2"));
std::unique_ptr<string> p3(p1.release());
cout << "*p3 : " << *p3 << endl;
cout << "p3 : " << p3 << endl;
cout << "p1 : " << p1 << endl;
std::unique_ptr<string> p4(new string("Arbitrary string 3"));
p3.reset(p4.release());
cout << "*p3 : " << *p3 << endl;
cout << "p3 : " << p3 << endl;
cout << "p4 : " << p4 << endl;
return EXIT_SUCCESS;
}
出力:
*p3 : Arbitrary string 2
p3 : 0x7d4c20
p1 : 0
*p3 : Arbitrary string 3
p3 : 0x7d5c80
p4 : 0