ikautak.log

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

More Effective C++ 項目33 末端でないクラスを抽象クラスにする

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

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

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

項目33 末端でないクラスを抽象クラスにする

以下のようなクラスがあったとき、

class A {
public:
  A& operator=(const A& a);
  ...
};

class B : public A {
public:
  B& operator=(const B& a);
  ...
};

B b1;
B b2;

A* pA1 = &b1;
A* pA2 = &b2;
...
*pA1 = *pA2; // 指し示しているのはBだが、
             // Aのoperator=が使われる

A部分だけがコピーされるような、部分代入が起きる。

operator=を仮想的にしたり、operator=内でdynamic_castを使ったり、変な対策はあるが、A部分を抽象クラスにするのが簡単らしい。

f:id:trisection:20130417223438p:plain

class AbstractA {
protected:
    AbstractA& operator=(const AbstractA& rhs);

public:
    virtual ~AbstractA() = 0;
    ...
};

class A : public AbstractA {
public:
    A& operator=(const A& rhs);
    ...
};

class B : public AbstractA {
public:
    B& operator=(const B& rhs);
    ...
};

これでoperator=も、項目3の配列のポリモーフィズムの問題の対策にもなる。

具象クラスが基底クラスとして利用されようとしているとき、言い換えるとクラスが新しい文脈で再利用されようとしているとき、抽象化は有効、とのこと。