ikautak.log

C/C++, Python, CUDA, Android, Linux kernel, Network, etc.

More Effective C++ 項目29 参照回数計測

新訂版 More Effective C++ (AddisonーWesley professional co)

新訂版 More Effective C++ (AddisonーWesley professional co)

  • 作者: スコット・メイヤーズ,安村通晃,伊賀聡一郎,飯田朱美,永田周一
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2007/06/29
  • メディア: 単行本(ソフトカバー)
  • 購入: 8人 クリック: 129回
  • この商品を含むブログ (43件) を見る

項目29 参照回数計測

参照回数計測は、複数のオブジェクトが同一の値を持ち、その値の表現を共有するテクニック。
newによってオブジェクトが割り当てられても中身では参照回数を+1するだけで、誰からも参照されなくなると自身をdeleteする。

参照回数を覚えるため、それぞれのクラスに参照回数を保持する領域が必要になる。
参照回数計測は実装であり、クラス名やインターフェース名に参照回数を計測していることを表す名前を含めるべきでない。
参照回数を管理しているとき、中身の値をポインタで直接操作されるケースに注意する。

基底クラスに参照回数計測の機能を持たせることができる。
参照回数の操作を自動的に行い、ポインタのように振舞うのがスマートポインタ。
既存のクラスにも参照回数計測を加えることが出来る。

サンプルの一部を写経。

template<class T>
class RCPtr {
public:
    RCPtr(T* realPtr = 0);
    RCPtr(const RCPtr& rhs);
    ~RCPtr();

    RCPtr& operator=(const RCPtr& rhs);

    T* operator->() const;
    T* operator*() const;

private:
    T *pointee;

    void init();
};

class RCObject {
public:
    RCObject();
    RCObject(const RCObject& rhs);
    RCObject& operator=(const RCObject& rhs);
    virtual ~RCObject() = 0;

    void addReference();
    void removeReference();

    void makeUnshareable();
    bool isShareable()const;

    bool isShared() const;

private:
    size_t refCount;
    bool shareable;
};

class String {
public:
    String(const char* value = "");

    char operator[](int index) const;
    char operator[](int index);

private:
    // Stringの値
    struct StringValue : public RCObject {
        char* data;

        StringValue(const char* initValue);
        StringValue(const StringValue& rhs);
        void init(const char* initValue);
        ~StringValue();
    };

    RCPtr<StringValue> value;
};

RCObjectを継承したStringValueを、スマートポインタとして振る舞うRCPtrにくるんでStringクラスが所有している。


参照回数計測は以下のケースで効果を発揮する。

  • 比較的多くのオブジェクトが、比較的少数の値を共有する
  • オブジェクトの値がメモリを消費し、生成と削除が高くつく