类的6个默认成员函数
一、构造函数
- 构造函数:是一个特殊的成员函数,
名字与类名相同,创建对象时由编译器自动调用
,保证每个成员函数都有一个初值, - 注意,
构造函数只是给类成员赋了一个初值,并不能称为给类成员进行初始化
,因为初始化只能有一次,而构造函数可以进行多次赋值,并且在对象生命周期内只调用一次,没有返回值。 - 初始化列表:
是初始化类中每个变量
,如果类成员包含引用类型成员变量、const成员变量、类类型成员变量(改类没有默认构造函数)则这些成员变量必须放在初始化列表位置进行初始化,另外,每个成员变量只能在初始化列表出现一次
。
注意:
- 函数名必须和类名相同;
- 无返回值;
- 构造函数可以重载;
- 构造函数的作用是初始化对象,并不是开空间创建对象;
- 如果类中没有显式定义构造函数,
编译器会自动生成一个默认无参数的构造函数,一旦用户显式定义,编译器就不再生成
; 无参数的构造函数和全缺省的构造函数都称为默认的构造函数
,并且默认的构造函数只能有一个,(我们没有显式定义构造函数,编译器默认生成的构造函数,都可以认为是默认成员函数)
二、析构函数
- 析构函数:
与构造函数功能相反
,注意析构函数不是完成对象的销毁
,局部对象的销毁是由编译器完成的,而对象在销毁前,会自动调用析构函数,完成一些对象的资源清理工作
。
注意:
- 构造函数名是在类名前加~符号;
- 无参数无返回值,就没有函数重载;
- 一个类有且只有一个析构函数,若未显式定义,编译器会默认生成一个;
- 在对象生命周期结束时,编译器系统自动调用析构函数
三、拷贝构造函数
- 拷贝构造函数:
用已存在类类型对象创建新对象时
由编译器自动调用,只有单个类类型引的型参,且一般用const修饰
。(注意深浅拷贝问题,会在后面解决)
注意:
- 拷贝构造函数是构造函数的重载形式;
参数必须使用引用传参,使用按值传参,会引发无穷递归调用进行创建临时对象
;- 最最重要的是:如果未显示定义拷贝构造函数,系统会默认生成按值传参的拷贝构造函数,即浅拷贝或值拷贝
四、运算符重载
- 运算符重载:是
为了加强代码的可读性而引入的
,运算符重载是具有特殊函数名的函数,有参数有返回值; - 对于赋值运算符重载问题:
一个类中一旦涉及资源管理问题,用户必须显式定义赋值运算符重载
(注意深浅拷贝问题)。函数原型为:返回值类型 operator 要重载的操作符 (参数)
注意:
- 不能通过链接其他符号来创建新的操作符,如operator@;
- 重载操作符必须有一个类类型的或枚举类型的操作数;
- 并且不能随意更改内置类型的操作符的含义;
- 作为类成员的重载函数时,形参看起来比操作数数目少一个,其实是有一个默认的形参this作为第一个参数;
最最最最最重要的是".*"、"sizeof"、"?:"、"."、"::"五个运算符不能重载
- 还有注意前置++(不带参数)、后置++(带一个参数)和=运算符的重载
五、取地址操作符重载和const修饰的去地址操作符重载
- 取地址操作符重载和const修饰的取地址操作符重载:一般不用重新定义,编译器会默认生成
简单归纳:
函数 | 返回值 | 参数 | 作用 |
---|---|---|---|
构造函数 | 无返回值 | 有参和无参两种 | 初始化对象 |
析构函数 | 无返回值 | 无参数 | 对象生命周期结束时,在对象删除前做清理工作 |
拷贝构造函数 | 无返回值 | 引用类型的参数 | 用已存在的对象创建新的对像 |
运算符重载 | 不定 | 至少有一个 | 方便C++中的操作 |
还有两个默认成员函数一般不用重新定义(取地址操作符重载和const修饰的去地址操作符重载)
注意:
- 1:const对象可以调用其他的const成员函数,而不能调用非const成员函数。
- 2.
非const对象既可以调用const成员函数也可以调用非const成员函数。
- 3.const成员函数可以调用其他的const成员函数,而不能调用非const成员函数。
- 4.
非const成员函数既可以调用其他的const成员函数,也可以调用非const成员函数。
#include<iostream>
#include<windows.h>
using namespace std;
class Date
{
public:
Date()
{
_year = 1998;
_month = 7;
_day = 22;
}
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
~Date()
{
_year = 1998;
_month = 7;
_day = 22;
}
Date(Date& ra)
{
_year = ra._year;
_month = ra._month;
_day = ra._day;
}
Date& operator=(Date& ra)
{
_year = ra._year;
_month = ra._month;
_day = ra._day;
return *this;
}
Date& operator+(int day)
{
_day += day;
return *this;
}
Date& operator-(int day)
{
_day -= day;
return *this;
}
Date& operator++()
{
_day += 1;
return *this;
}
Date operator++(int)//后置++因为要返回没有加1之前的,所以创建类类型变量(不能是类类型的引用)存储起来,方便返回,注意和前置++返回值及参数的区别
{
Date temp = *this;
_day += 1;
return temp;
}
Date& operator--()
{
_day -= 1;
return *this;
}
Date operator--(int)
{
Date temp = *this;
_day -= 1;
return temp;
}
bool operator>(const Date& ra)const
{
if (_year > ra._year)
{
return true;
}
else if(_year==ra._year &&_month>ra._month )
{
return true;
}
else if (_year == ra._year &&_month == ra._month&&_day > ra._day)
{
return true;
}
else
{
return false;
}
}
bool operator==(const Date& ra)const
{
if (_year == ra._year &&_month == ra._month&&_day == ra._day)
{
return true;
}
else
{
return false;
}
}
bool operator>=(const Date& ra)const
{
if (this->operator>(ra) || this->operator==(ra))
{
return true;
}
else
{
return false;
}
}
bool operator < (const Date& ra)const
{
if (this->operator>(ra))
{
return false;
}
else
{
return true;
}
}
bool operator<=(const Date& ra)const
{
if (this->operator<(ra) || this->operator==(ra))
{
return true;
}
else
{
return false;
}
}
bool operator!=(const Date& ra)const
{
if (this->operator==(ra))
{
return false;
}
else
{
return true;
}
}
void Show()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date a(2019, 10, 20);
a.Show();
Date b(a);
b.Show();
Date c(2019, 10, 22);
c.Show();
//cout << a>b << endl;
//cout << a.==b << endl;
//cout << a>=c << endl;
cout << a!=b << endl;
cout << a<=b<< endl;
cout << a!=c << endl;
cout << a<=c << endl;
system("pause");
return 0;
}