(原創) 為什麼derived-class會去執行base-class的default constructor? (C/C++)
執行以下程式,會發現一個有趣的現象,明明我是呼叫了derived-class的constructor,為什麼會去執行base-class的default constructor呢?
/* 2
(C) OOMusou 2007 http://oomusou.cnblogs.com3

4
Filename : Constructor_sequence.cpp5
Compiler : Visual C++ 8.0 / gcc 3.4.2 / ISO C++6
Description : Demo the sequence of base-class default constructor and derived-class constructor7
Release : 02/15/2007 1.08
*/9
#include <iostream>10
#include <string>11

12
using namespace std;13

14
class Student {15
public:16
string name;17
public: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

28
class Bachelor : public Student {29
public: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

45
int 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的原因。
再看看下一個例子:
/* 2
(C) OOMusou 2007 http://oomusou.cnblogs.com3

4
Filename : Constructor_NoBaseClassDefaultConstructor.cpp5
Compiler : Visual C++ 8.0 / gcc 3.4.2 / ISO C++6
Description : Demo how to call base class constructor7
Release : 02/16/2007 1.08
*/9
#include <iostream>10
#include <string>11

12
using namespace std;13

14
class Student {15
public:16
string name;17
public:18
Student(const char *name) {19
this->name = string(name);20
}21
};22

23
class Bachelor : public Student {24
public:25
string lab;26
27
public:28
Bachelor(const char *name, const char *lab) : Student(name) {29
this->lab = string(lab);30
}31
}; 32

33
int 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++) (OO C++) (02/15/2007 更新2.0)中所說的,很多地方都要用到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的程式。
這也再次證明的default constructor的重要性,就算表面上看起來沒用到,但卻隱含的被呼叫了,所以我們應該養成好習慣,自己寫default constructor,而不要讓compiler幫我們自動產生synthesized default constructor。
See Also
(原創) default constructor的迷思 (C/C++)
(原創) derived-class要怎麼呼叫base-class的constructor? (C/C++)
Reference
C++ Primer 4th section 15.4.2 p.581


Student()
浙公网安备 33010602011771号