C++Builder2009の新機能 その5 (std::unique_ptr編)

CodeGearの高橋さんから、C++0xのunique_ptrが使えるということで試してみた。

今までのauto_ptrだとこんな感じ。

#include <memory>
// 中略
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  std::auto_ptr<TStringBuilder> pBuffer(new TStringBuilder());

  pBuffer->Append(UnicodeString("abcdef"));
  pBuffer->Append(UnicodeString("|"));
  pBuffer->Append(UnicodeString("123456"));

  std::auto_ptr<TStringBuilder> pBuffer2 = pBuffer;

  ShowMessage(pBuffer->ToString());    // ポインタの所有権が移った段階で、ぬるぽでこける
}

auto_ptrの場合、ポインタの所有権が別のauto_ptrに移ったときに、前の所有者の生ポインタがNULLとなるので、前の所有者でポインタにアクセスしようとすると、EAccessViolationが発生しエラーになる。

一方、std::unique_ptrはboost::scoped_ptrと同様、原則としてコピーが出来ない(コンパイル時にエラーとなる)ので、ポインタをスコープの最後まで管理してくれる。

#include <memory>
// 中略
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  std::unique_ptr<TStringBuilder> pBuffer(new TStringBuilder());

  pBuffer->Append(UnicodeString("abcdef"));
  pBuffer->Append(UnicodeString("|"));
  pBuffer->Append(UnicodeString("123456"));

  //std::unique_ptr<TStringBuilder> pBuffer2 = pBuffer;	// そもそもコピー不可
  TStringBuilder* tmp = pBuffer.get();	// どうしても生ポインタが欲しい場合は、getメソッドで。

  ShowMessage(tmp->ToString());  // 生ポインタでアクセスしてみる
}

std::unique_ptrとboost::scoped_ptrの違いは調べてみないと判らないけど、使い勝手は変わらない感じ。使うとしたらstd::unique_ptrがC++0x標準なので、こっちのほうがいいかも。