[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;
}