https://ja.cppreference.com/w/cpp/language/classes.html

用語

  • メンバ関数:いわゆるメソッド
  • メンバ変数:いわゆるメンバ
  • オブジェクト?:いわゆるインスタンス

クラスメソッドのオーバーライド

仮想関数についてのまとめ(virtualとかoverrideとかがわかってなかったのでメモ)
仮想関数指定子 - cppreference
仮想関数 - C++入門

  • 例えば親クラス base がメソッド int run(int a) を持っているとして、それぞれの派生クラスでその挙動を変えたい時に関数のオーバーライドを用いる
    • オーバーロードではない(同じ関数名で、引数によって呼ぶ関数を変えることを、関数のオーバーロードと呼ぶ)
  • virtual int run(int a) とすればその関数が仮想関数であることを示すことができ、派生クラスでオーバーライドできる
    • 派生クラスでは int run(int a) override とする
      • キーワード override はそれが基底クラスの仮想関数をオーバーライドしていることを示す
      • オーバーライドしようと思っていたのに誤って int run(double a) とした場合、これは基底クラスのオーバーライドではなく派生クラスオリジナルのメソッドになってしまうが、ここに override をつけていると(引数の型が違うから)エラーが出る
  • 末尾に = 0 を付けると純粋仮想関数になり、基底クラスで実装する必要がなくなる
    • 純粋仮想関数をもつクラスは抽象クラス となり、インスタンス化できなくなる

継承時のアクセス指定子

派生クラス - cppreference.com
class Hoge : <アクセス指定子> BaseClass

  • private, protected, publicのいずれか
  • 基底クラスのpublic/protectedなメンバーが、ここで指定したとおりにアクセスできるようになる
    • たとえばprivateにした際、基底クラスのpublic/protectedなメンバーは、派生クラスにおいてprivateになる
      • 基底クラスに private: int a; があったら、派生クラスでは public: int a; としてアクセスできる
  • 基底クラスのprivateなメンバーは、アクセス指定子に関係なく、(friendが付かない限り)派生クラスでもprivate

コンストラクタ

  • 継承時は基底クラスのものが先に呼ばれる
    • デストラクタも同様(オーバーライドしていても)
      class.cpp
#include <bits/stdc++.h>
 
class Parent {
 public:
  Parent() {
    std::cout << "   from Parent" << std::endl;
  }
  ~Parent() {
    std::cout << "   Bye Parent" << std::endl;
  }
};
 
class Child : Parent {
 public:
  Child() {
    std::cout << "   from Child" << std::endl;
  }
  ~Child() {
    std::cout << "   Bye Child" << std::endl;
  }
};
 
int main() {
  {
    std::cout << ">> Create Parent" << std::endl;
    auto p = Parent();
    std::cout << ">> End of scope" << std::endl;
  }
  {
    std::cout << ">> Create Child" << std::endl;
    auto c = Child();
    std::cout << ">> End of scope" << std::endl;
  }
  return 0;
}
 
// $ clang++ a.cpp && ./a.out
// >> Create Parent
//    from Parent
// >> End of scope
//    Bye Parent
// >> Create Child
//    from Parent
//    from Child
// >> End of scope
//    Bye Child
//    Bye Parent
  • コンストラクタを仮想関数にすることは出来ない