32章 privateな継承

http://www.geocities.jp/ky_webid/cpp/language/032.html

今まで継承を行う際、

class CSub : public CSuper 

のようにpublicと書いていました。

実はprivateやprotectedも指定できるらしいのです。

今回はまず、privateな継承から学んでいきたいと思います。

privateな継承を行うと、スーパークラスの全てのメンバが、サブクラスのインスタンスからはprivateのように見えるというものです。

#include <iostream>
using namespace std;

class CSuper {
public:
    void Set (int num) { m_num = num; }
    int Get () const { return m_num; }
private:
    int m_num;
};

class CSub : private CSuper {
public:
    // これらは今まで通りpublicに見えているので大丈夫
    CSub (int num) { Set(num); }
    void output () { cout << Get() << endl; }
};

int main() {
    CSub obj(100);
    
    //obj.Set(200); // これはprivateに見えてるのでコンパイルエラーになる
    obj.output();
    
    return 0;
}
$ main
100

なるほど。しかしあまりピンと来ないですね。

CSuperが元々メンバ関数をprotectedで提供していれば、publicな継承でも同じことが実現できますよね。

何かの事情でpublicなメンバ関数を持つクラスを外部から見せなくしたいようなケースでprivateな継承を使うんでしょうか。ちょっとまだよくわからないです。

さて、privateな継承ですが、publicな継承ともうひとつ違う部分があります。

privateな継承ではサブクラス型のオブジェクトをスーパークラス型で受け取れないというところです。

int main() {
    CSuper super_obj;
    CSub sub_obj(100);
    
    CSuper* p1 = &super_obj;
    CSuper* p2 = &sub_obj; // こちらはコンパイルエラー
    
    return 0;
}
$ cl /W4 /EHsc main.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
main.cpp(24) : error C2243: '型キャスト' : 'CSub *' から 'CSuper *' の変換は存在しますが、アクセスできません。

これでは多態性が実現できませんね。

ますます用途がわからなくなってきました。