読者です 読者をやめる 読者になる 読者になる

Accelerated C++第14章

C++ Accelerated C++

お言葉

2つの独立した抽象クラスであるべきものを1つのクラスにするということは、しばしばデザインの弱さを示しているのです。

ハンドル

  • オブジェクトへのポインタを保持する
  • ハンドルが結び付けられているオブジェクトの型とは独立している
  • ポインタと同じ振る舞い

低レベルなデータ構造であるポインタの問題

  • ポインタのコピーは指しているオブジェクトのコピーにならない。うっかり同じオブジェクトを指す2つのポインタを作ってしまうと、後で驚くようなことになる。
  • ポインタの破棄がオブジェクトの破棄にはならない。これはメモリリークを起こしてしまう。
  • オブジェクトを破棄してポインタだけ残すと、これはどこも指さないポインタになってしまう。このポインタを使うと動作がどうなるかわからない。
  • ポインタを初期化しないで生成すると、そのポインタはオブジェクトを指していないことになる。このポインタを使うとづ長がどうなるかわからない。

operator->()

  • C++の言語仕様では、-> はポインタとして扱えるものを戻す
  • operator-> を定義すると、ハンドルへの関数呼び出しの要素を、ハンドルが保持するポインタへ渡せる

つまり

x->y

(x.operator->())-y

と同じことになる。これは素晴らしい。

テンプレート特化

  • 特定の引数形に対応した特定バージョンのテンプレート関数を定義できる
// ジェネリック関数 clone()
template <class T> T* clone(const T* tp)
{
    return tp->clone();
}

// clone() をVec<char>* 型に特化したもの
template <>
Vec<char>* clone(const Vec<char>* vp)
    return new Vec<char>(*vp);
}