2006-06-18
前回はクラスの継承を構造体を使って説明しました。話を単純にするために、やや誤解を招く恐れのある書き方をしてしまったので、早めにフォローしておくことにします。今回は、その誤解を招く恐れのある部分に関連した、基底クラスへのアクセス制御です。
前回は、「このようにクラスを継承するときには、structやclassといったクラスキーとクラス名の後に、継承しようとするクラス名をコロン : で区切って記述します。」と書きました。しかし、この書き方をした場合、使用したクラスキーによって意味が異なります。
クラスキーが struct の場合、クラスのメンバはデフォルトで公開(public)でしたが、継承の場合も基底クラスはデフォルトで公開になります。それに対して、クラスキーが class の場合、クラスのメンバがデフォルトで非公開(private)であるように、基底クラスもデフォルトでは非公開になります。
基底クラスが非公開(private)ということは、基底クラスの持つ全メンバは、派生クラスの非公開メンバとして扱われます。また、そのクラスのメンバ関数の中や静的データメンバの初期化を除き、非公開の基底クラスへのポインタや参照に、暗黙的に型変換されることもありません。
struct A
{
int a;
int foo(int arg);
};
class B : A
{
};
B b;
A* p = &b; // エラー
このように、メンバに対するものと同様、基底クラスに対しても公開や非公開(そして限定公開)といったアクセス制御があります。上記はデフォルトのアクセス制御についての話でしたが、明示的にアクセス制御を行うこともできます。その場合、つぎのように記述します。
class B : public A
{
};
B b;
A* p = &b; // OK
すなわち、基底クラスを指定する際に、publicやprivate(およびprotected)といったアクセス指定子を記述すればよいのです。
ここで、これまではあまり詳しく触れてこなかった限定公開(protected)についても書いておきます。限定公開というのは、公開と非公開の中間的な存在で、派生クラスからのアクセスを許可するものです。すなわち、そのクラスと派生クラス(および、さらにその派生クラス)からは普通にアクセスすることができますが、クラスの外部からのアクセスは禁止されます。
メンバを非公開(private)にしてしまうと、いくら継承によってクラスの性質が引き継がれるといっても、派生クラスからそのメンバにアクセスすることができなくなります。派生クラスからもメンバにアクセスする必要があるなら、限定公開にする必要があります。
Comment