[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[jfriends-ml 12251] C++ の public 継承と private 継承
こんばんは遠藤です。
今日出てきたC++のpublic継承とprivate継承ですが
特にprivateの方はJavaにはない機能なのでご説明します。
まずpublic継承の方は、Javaの継承とほぼ同様です。
たとえば、Javaで
class A {
public void foo() {}
}
class B extends A {
public void bar() {}
}
と書くのは、C++のpublic継承を使って
class A {
public:
void foo() {
printf("foo called\n\n");
}
};
class B: public A { //継承の時に"public"を指定している
public:
void bar() {
printf("calling foo()\n");
foo(); //Aから継承したメソッドをBから呼ぶ
}
};
と書くのとほぼ同様で
int main(int argc, char *argv[]) {
B* b = new B();
b->bar();
b->foo(); //Aから継承したメソッドを外から呼ぶ
A *a = b; //B型のオブジェクトを、A型として扱う
delete b;
}
のように使えます。
Aをpublic継承するということは、
Aから継承したものを、Aとそのまま公開しているので
「publicな継承」と解釈できます。
一方で、private継承ですが、
Aは同じとして、継承の際にprivateを指定するのだけ変えます。
class B: private A { //継承の時にprivateを指定している
public:
void bar() {
printf("calling foo()\n");
foo(); //これはOK
//privateフィールドのpublicメソッドにアクセスできるのと同様
}
};
int main(int argc, char *argv[]) {
B* b = new B();
b->bar();
b->foo(); // コンパイルエラー
A *a = b; // コンパイルエラー
// BがAを継承しているのは、"private"なので
// 外からAのメソッドにアクセスしたり、
// A型のポインタに代入できない
// g++では `A' is an inaccessible base of `B' と表示される
delete b;
}
のように
1. Bクラスの中から、Aのpublicメソッドにはアクセスできる
2. Bクラスの外では、Aのpublicメソッドにアクセスできない
となります。
この2番目の、特徴は不便なように思えるかも知れませんが
実際には、
Aを継承していることを、外部には隠すことができる
と解釈すると
Bは、Aの実装を継承して使いたいが、
Aのpublicメソッドを、B型としては公開したくない。
というケースで使うことができます。
今日出てきたAdapterパターンでは、
Adapterは、Adapteeの実装を継承して使いたいが、
Adapteeのpublicメソッドを、Adapter型としては公開したくない。
ので、private継承を使うという説明でした。
--
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
遠藤 康裕 quiver2k@xxxxxxxxx
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#include <stdio.h>
class A {
public:
void foo() {
printf("foo called\n\n");
}
};
class B: private A {
public:
void bar() {
printf("calling foo()\n");
foo(); //A©çp³µ½\bhðB©çÄÔ
}
};
int main(int argc, char *argv[]) {
B* b = new B();
b->bar();
// b->foo(); //A©çp³µ½\bhðO©çÄÔ
// A *a = b; //B^ÌIuWFNgðAA^Ƶĵ¤
delete b;
}