C++で基底クラス(スーパークラス)のコンストラクタを呼び出すルールとは?
C++では、既存のクラスを継承して新しい派生クラスを作成できます。派生クラスのオブジェクトを生成する際、そのコンストラクタが呼び出される前に、必ず基底クラス(スーパークラス)のコンストラクタが呼び出されます。Javaとは異なり、C++にはsuperのような基底クラスを参照するキーワードは存在しません。
呼び出しのルールは以下のとおりです。
- 基底クラスのコンストラクタが引数なしで定義されている場合、派生クラスのオブジェクト生成時に自動的に呼び出されます。
- 基底クラスのコンストラクタが引数付きで定義されている場合は、派生クラスのコンストラクタのメンバ初期化子リストで明示的に呼び出す必要があります。
まずは、引数なしのコンストラクタの動作を確認してみましょう。
例:引数なしのコンストラクタ
#include <iostream>
using namespace std;
class MyBaseClass {
public:
MyBaseClass() {
cout << "Constructor of base class" << endl;
}
};
class MyDerivedClass : public MyBaseClass {
public:
MyDerivedClass() {
cout << "Constructor of derived class" << endl;
}
};
int main() {
MyDerivedClass derived;
}
出力結果
Constructor of base class
Constructor of derived class
この例では、MyDerivedClassのオブジェクトを生成するだけで、基底クラスのコンストラクタが自動的に呼び出されていることがわかります。呼び出し順序は必ず「基底クラス → 派生クラス」の順になります。
次に、引数を取るコンストラクタの場合を見てみましょう。
例:引数付きのコンストラクタ
#include <iostream>
using namespace std;
class MyBaseClass {
public:
MyBaseClass(int x) {
cout << "Constructor of base class: " << x << endl;
}
};
class MyDerivedClass : public MyBaseClass { // メンバ初期化子リストで基底クラスのコンストラクタを呼び出す
public:
MyDerivedClass(int y) : MyBaseClass(50) {
cout << "Constructor of derived class: " << y << endl;
}
};
int main() {
MyDerivedClass derived(100);
}
出力結果
Constructor of base class: 50
Constructor of derived class: 100
このように、基底クラスに引数付きコンストラクタしか定義されていない場合は、: MyBaseClass(50)のようにメンバ初期化子リストを使って明示的に呼び出します。これを省略するとコンパイルエラーになるため注意が必要です。
まとめ
- 引数なしの基底クラスコンストラクタは、派生クラスのオブジェクト生成時に自動的に呼び出される。
- 引数付きの場合は、派生クラスのコンストラクタのメンバ初期化子リストで明示的に呼び出す必要がある。
- コンストラクタの実行順序は必ず基底クラスが先、派生クラスが後。
-
Java 9のSubscriptionインターフェースのルールとは?基本から徹底解説
Java 9で導入されたReactive Streams(java.util.concurrent.Flow)において、SubscriptionはPublisherとSubscriberの間のデータ交換を仲介するための重要な役割を担います。Subscriptionは必ず1つのPublisherと1つのSubscriberのペアでのみ共有されます。そのため、subscribe()メソッドは生成されたSubscriptionを返さず、戻り値はvoidになっています。SubscriptionはonSubscribe()メソッドのコールバックを通じてのみSubscriberへ渡されます。Subscri
-
Java 9のSubscriberインターフェースのルールとは?Reactive Streamsの規約を徹底解説
Java 9で導入されたReactive Streams(Flow API)において、SubscriberインターフェースはPublisherを購読(サブスクライブ)し、データを受け取る役割を担います。具体的には、onNext()メソッドでアイテムを順次受け取り、onError()メソッドでエラーメッセージを受け取り、onComplete()メソッドで「これ以上アイテムは届かない」ことを示す完了シグナルを受け取ります。 これらのシグナルが発生する前に、必ずPublisher側からonSubscribe()メソッドが呼び出されます。これは、SubscriberとPublisherの間でSubsc