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
