Slip Ahead Logging

It's not your fault at all.

C++ における private 継承

[:title=CRTP の noncopyable の例]に次のようなコード例があった.

template <class T>
class NonCopyable
{
  protected:
    NonCopyable() {}
    ~NonCopyable() {} /// protected な非仮想デストラクタ

  private: 
    NonCopyable(const NonCopyable&);
    T& operator=(const T&);
};

class CantCopy : private NonCopyable <CantCopy>
{
  // some implementation
};

ここで CantCopy は private 継承を行なっている.そもそも private 継承と public 継承との違いが分からなかったので調べた.

Effective C++ #39 "private 継承は賢く使おう" に,次のようなコードがある.

class Person {};
class Student: private Person {};  // private inheritance

void eat(const Person& p);
void study(const Student& s);

Person p;
Student s;

eat(p); // OK
eat(s); // NG: Person を期待する関数に Student を渡しても,コンパイラによるアップキャストは行われない!

こうした挙動は「public 継承が is-a 関係を表すのに対し,private 継承は is-implemented-in-terms-of 関係を表す」と表現されている.うーん,分かりやすい.