一、前言
本章是继C++类和对象启点之章的后续,进一步深入学习掌握C++类和对象
二、类的6个默认成员函数汇总
对于任何一个类来说,在我们不主动写默认成员函数时,会自动生成默认成员函数,总共有6个默认成员函数
- 汇总示图:
三、构造函数
引入:
在C语言数据结构时,创建结构变量我们经常需要自行调用结构初始化函数,否则可能会报错,为了避免忘记调用初始化函数,C++对此做出了优化,即在创建对象时自动调用初始化函数,也就是构造函数
概念:
构造函数是特殊的成员函数,在由类创建对象时对对象的成员变量进行初始化,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的初始值,并且在对象的生命周期内只调用一次
特性:
函数名必须和类名一致
无返回值(没有返回值并不是void,void返回值是空)
对象实例化时编译器自动调用对应的构造函数(在C语言上的优化)
构造函数可以重载(可以存在多种初始化方式)
示例:
class Date { public: // 1.无参构造函数 Date() { cout << "Date()" << endl; } // 2.带参构造函数 Date(int year, int month, int day) { cout << "Date(int year, int month, int day)" << endl; _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; }; void TestDate() { Date d1; // 调用无参构造函数 Date d2(2022, 2, 1); // 调用带参的构造函数 // 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明 // 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象 Date d3(); }
5. 如果类中没有显式定义构造函数(我们没有主动写),则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成
- 示例:
class Date { public: /* // 如果用户显式定义了构造函数,编译器将不再生成 Date (int year, int month, int day) { _year = year; _month = month; _day = day; } */ private: int _year; int _month; int _day; }; void Test() { // 没有主动写构造函数,此处会调用编译器生成的默认构造函数 Date d; }
- 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个(默认构造函数:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数)
- 示例:
class Date { public: //构造函数可以重载,因为可能我们想初始化对象的方式有多种 Date()//无参构造函数 { _year = 1900; _month = 1; _day = 1; } Date(int year = 1900, int month = 1, int day = 1)//全缺省构造函数 { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; }; // 以下测试函数能通过编译吗? void Test() { Date d1; }
解释:
对于不传参构造来说,初始化调用无参构造函数或者全缺省构造函数都行,而编译器不能明确知道该调用哪一个(存在二义性/矛盾),也就报错了
编译器生成默认的构造函数其实并不会对对象的内置类型(int/char/float等等)进行处理(因为并不知道怎样初始化好),但是会对自定义类型进行调用其类型自身的默认构造函数
示例:
class Time { public: Time()//自己写的默认构造函数 { cout << "Time()" << endl; _hour = 0; _minute = 0; _second = 0; } private: int _hour; int _minute; int _second; }; class Date { /*Date() { cout << "Date" << endl; }*/ private: // 基本类型(内置类型) int _year; int _month; int _day; // 自定义类型 Time _t; }; int main() { Date d; return 0; }
注:如果自定类型的默认构造函数也是编译器默认生成的话,还是相当于不会处理
注:所以一般来说都建议自己写构造函数进行初始化成员变量