C++ 6个默认成员函数
目录:
1.构造函数:
2.拷贝构造函数:
3.析构函数:
4.赋值操作符重载:
5.取地址操作符重载:
6.const修饰的取地址操作符重载:
1.构造函数:
构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。在对象的生命周期内只调用一次,目的是保证对象内的数据成员都有一个初始化的值。
#include <iostream> #include <Windows.h> using namespace std; class Data{ public: //构造函数 Data(int year = 1991 , int month = 1, int day = 1)//缺省参数 //初始化列表,其中初始化列表的复制顺序是按照参数声明的顺序来赋值的 :_year(year) , _month(month) , _day(day) { //_year = year; //_month = month; //_day = day; cout << "Data!" << endl; } private: int _year; int _month; int _day; }; int main(){ Data d; Data d1(2018,7,7); system("pause"); return 0; }
运行结果如下:
Data! 1991-1-1 Data! 2018-7-7 请按任意键继续. . .
以上代码就是我们的构造函数,从上面我们可以看到它的特点:
函数名与类名相同
没有返回值
对象创建时只调用一次
构造函数可以有多个(函数的重载,后面会介绍)
如果没有定义构造函数,编译器会自动生成一个构造函数
2.拷贝构造函数:
拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。
#include <iostream> #include <Windows.h> using namespace std; class Data{ public: //构造函数 Data(int year = 1991, int month = 1, int day = 1) //初始化列表,其中初始化列表的复制顺序是按照参数声明的顺序来赋值的 :_year(year) , _month(month) , _day(day) { //_year = year; //_month = month; //_day = day; cout << "Data1!" << endl; cout << _year << "-" << _month << "-" << _day << endl; } //构造函数的重载 Data(const Data& d){ _year = d._year; _month = d._month; _day = d._day; cout << "Data2!" << endl; cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; }; int main(){ Data d1(2018, 7, 7); Data d(d1); system("pause"); return 0; }
运行结过如下:
Data1! 2018-7-7 Data2! 2018-7-7 请按任意键继续. . .
拷贝构造函数特点如下:
拷贝构造函数是构造函数的重载,具有与其相同的性质
参数必须用引用传递
如果没有定义,会自动合成一个默认的拷贝构造函数
3.析构函数:
析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。
#include <iostream> #include <Windows.h> using namespace std; class Data{ public: . . . ~Data(){ cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; }; void test(){ Data d(2018,1,1); } int main(){ test(); system("pause"); return 0; }
运行结果如下:
Data1! 2018-1-1 ~Data! 请按任意键继续. . .
析构函数特点如下:
函数名是”~类名”
析构函数无返回值
一个类中只能有一个析构函数,有且只有一个。如果没有定义,编译器会自动生成。
在对象的生命周期结束时,会自动调用这个析构函数
析构函数的目的是回收一些空间资源等,而不是删除其对象的数据。
4.赋值操作符重载:
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。
#include <iostream> #include <Windows.h> using namespace std; class Data{ public: . . . Data& operator = (Data& d){ _year = d._year; _month = d._month; _day = d._day; return d; } void displayData(){ cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; }; void test(){ Data d1(2018, 11, 11); cout << "d1:"; d1.displayData(); Data d2; cout << "赋值之前d2:"; d2.displayData(); d2 = d1; cout << "赋值之后d2:"; d2.displayData(); } int main(){ test(); system("pause"); return 0; }
运行结果:
d1:2018-11-11 赋值之前d2:1990-1-1 赋值之后d2:2018-11-11 请按任意键继续. . .
5.取地址操作符重载:
#include <iostream> #include <Windows.h> using namespace std; class Data{ public: . . . Data* operator & (){ return this; } private: int _year; int _month; int _day; }; void test(){ Data d1(2018, 11, 11); cout << "0x" << &d1 << endl; } int main(){ test(); system("pause"); return 0; }
运行结果:
0x010CF95C 请按任意键继续. . .
6.const修饰的取地址操作符重载:
#include <iostream> #include <Windows.h> using namespace std; class Data{ public: . . . const Data* operator & () const { return this; } private: int _year; int _month; int _day; }; void test(){ const Data d1; cout << "0x" << &d1 << endl; } int main(){ test(); system("pause"); return 0; }
运行结果: 0x00D9F998 请按任意键继续. . .