執行以下程式,會發現一個有趣的現象,明明我是呼叫了derived-class的constructor,為什麼會去執行base-class的default constructor呢?

1/**//* 
2
4Filename : Constructor_sequence.cpp
5Compiler : Visual C++ 8.0 / gcc 3.4.2 / ISO C++
6Description : Demo the sequence of base-class default constructor and derived-class constructor
7Release : 02/15/2007 1.0
8*/
9#include <iostream>
10#include <string>
11
12using namespace std;
13
14class Student {
15public:
16 string name;
17public:
18 Student() {
19 cout << "student's default constructor" << endl;
20 }
21
22 Student(const char *name) {
23 this->name = string(name);
24 cout << "student's 1 argument constructor" << endl;
25 }
26};
27
28class Bachelor : public Student {
29public:
30 Bachelor() {
31 cout << "bachelor's default constructor" << endl;
32 }
33
34 /**//* Bachelor(const char *name) : Student() {
35 this->name = string(name);
36 cout << "bachelor's 1 argument constructor" << endl;
37 }*/
38
39 Bachelor(const char *name) {
40 this->name = string(name);
41 cout << "bachelor's 1 argument constructor" << endl;
42 }
43};
44
45int main() {
46 Bachelor bachelor("John");
47 cout << bachelor.name << endl;
48}

執行結果

student's default constructor
bachelor's 1 argument constructor
John

46行明明是呼叫derived-class的constructor,但執行結果卻執行過base-class的default constructor,為什麼會這樣呢?

由於derived-class是繼承於base-class,所以有些data member是從base-class繼承而來的,那些data member該怎麼做初始化呢?靠base-class的default constructor!!所以39行~42行是我們為derived-class寫的constructor,而compiler會自動改成如34行~37行那樣,在constructor initializer list加上Student()來呼叫base-class的default constructor,這也是為什麼會執行base-class的default constructor的原因。

再看看下一個例子:

 

1/**//* 
2(C)
4Filename : Constructor_NoBaseClassDefaultConstructor.cpp
5Compiler : Visual C++ 8.0 / gcc 3.4.2 / ISO C++
6Description : Demo how to call base class constructor
7Release : 02/16/2007 1.0
8*/
9#include <iostream>
10#include <string>
11
12using namespace std;
13
14class Student {
15public:
16 string name;
17public:
18 Student(const char *name) {
19 this->name = string(name);
20 }
21};
22
23class Bachelor : public Student {
24public:
25 string lab;
26
27public:
28 Bachelor(const char *name, const char *lab) : Student(name) {
29 this->lab = string(lab);
30 }
31};
32
33int main() {
34 Bachelor bachelor("John","PECLab");
35 cout << bachelor.name << endl;
36 cout << bachelor.lab << endl;
37}

執行結果
John
PECLab

base-class和derived-class都沒有default constructor,compiler也過了,並且可以正常執行,所以若目前用不到default constructor,是可以省略不寫,不過這並不是一個好的practice 很多地方都要用到default constructor,而且C++又有C的built-in type的包袱,建議還是都要寫default consturctor。


28行derived-class的constructor,自己呼叫了base-class的constructor,也就是說,若derived-class的constructor自己呼叫了base-class的constructor,則compiler不會再自動加上呼叫base-class的default constructor的程式,反之,若derived-class的constructor沒有呼叫base-class的constructor,則compiler會如同前一個例子自動加上呼叫default constructor的程式。