C++ 中,派生类什么时候可以不定义构造函数,什么时候必须定义构造函数?
派生类是否需要定义构造函数,取决于基类的构造函数情况。
前提:派生类的构造函数负责初始化整个对象,包括基类部分和派生类新增的成员。
情况1、如果基类:
(1)不定义构造函数,or
(2)有无参构造函数,or
(3)定义了带默认形参值的构造函数,
这3种情况本质上就是初始化基类数据时可以不需提供参数,这样,派生类即使不定义构造函数,继承到的基类数据也可以被初始化,所以在这些情况下,派生类可以不定义构造函数。
情况2、如果基类定义了带参数的构造函数且没有默认形参值,
则在初始化基类数据的时候,就必须提供具体的参数值,所以派生类在初始化这些基类的数据的时候,也需要提供具体参数值,这些参数值必须在构造函数里给出,所以派生类必须定义构造函数。
总之,派生类是否需要定义构造函数,取决于初始化基类对象时是否必须提供参数。
如果可以不提供参数(上述情况1),派生类就可以不定义构造函数;
如果必须提供参数(上述情况2),派生类就必须定义构造函数。
情况1:
(1)不定义构造函数实例:
#include <iostream>
using namespace std;class Date {
public:void setDate(int y, int m, int d) {year = y;month = m;day = d;}void showDate() {cout << year << "-" << month << "-" << day << endl;}private:int year, month, day;
};int main() {Date a_date; // 创建Date类的对象,会调用默认构造函数a_date.setDate(2024, 3, 25); // 设置日期a_date.showDate(); // 输出日期Date b_date; // 再次创建Date类的对象b_date.showDate(); // 输出默认初始化的日期return 0;
}
(2)定义无参构造函数实例:
#include <iostream>
using namespace std;class Date {
public:Date() { // 无参构造函数year = 1;month = 1;day = 1;}void showDate() {cout << year << "-" << month << "-" << day << endl;}
private:int year, month, day;
};int main() {Date b_date; // 使用无参构造函数创建对象b_date.showDate(); // 输出日期return 0;
}
(3)定义带默认形参值的构造函数实例:
#include <iostream>
using namespace std;class Date {
public:Date(int y = 1, int m = 1, int d = 1) { // 带默认形参值的构造函数year = y;month = m;day = d;}void showDate() {cout << year << "-" << month << "-" << day << endl;}private:int year, month, day;
};int main() {Date today; // 使用默认参数初始化,即今天的日期是 1-1-1today.showDate(); // 输出日期Date birthday(1999, 5, 23); // 使用具体参数初始化,即生日是 1999-5-23birthday.showDate(); // 输出日期return 0;
}
以Date为基类产生派生类时,这3种情况本质上就是初始化基类Date的数据时可以不需提供参数,这样,派生类即使不定义构造函数,继承到的基类数据也可以被初始化,所以在这些情况下,派生类可以不定义构造函数。
情况2:
定义带参数的构造函数且没有默认形参值
#include <iostream>
using namespace std;class Date {
public:Date(int y, int m, int d) { // 构造函数year = y;month = m;day = d;}void showDate() {cout << year << "-" << month << "-" << day << endl;}
private:int year, month, day;
};int main() {Date a_date(2024, 3, 25); // 必须使用带参数的构造函数创建对象a_date.showDate(); // 输出日期return 0;
}
以Date为基类产生派生类时,派生类在初始化基类Date的数据时,需要提供具体参数值,这些参数值必须在构造函数里给出,所以派生类必须定义构造函数。