类的默认成员函数,构造函数,拷贝构造,析构函数,赋值运算符重载
1.隐含的this指针
1.每个成员函数都有一个指针形参,她的名字是固定的,成为this指针,this指针是隐式的。(构造函数比较特殊,没有这个隐含的 this指针)
2.编译器会对成员函数进行处理,在对象调用成员函数时,对象地址作为实参传递给成员函数的第一个形参this指针
3.this指针是成员函数隐含指针形参,是编译器自己处理的。我们不能在成员函数的形参中添加this指针的参数定义,也不能在调用 时显示传递对象的地址给this指针
2.类的默认成员函数
一 构造函数
日期的成员变量是私有的,我们怎么来初始化这些私有的成员变量?
成员变量是私有的,要对他进行初始话,必须要用一个公有成员函数来进行,同时这个函数仅在定义对象时自动执行一次,这时调用的函数称为构造函数,构造函数是特殊的成员函数。
特征如下:
1.函数名与类名相同
2.无返回值
3.对象构造(对象实例化)时系统自动调用对应的构造函数
4.构造函数可以重载
5.构造函数可以在类中定义,也可以在类外定义
6.如果类定义中没有给出构造函数,则编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就 不会自动生成缺省的构造函数
7.无参构造函数和全缺省的构造函数都认为是缺省的构造函数,并且缺省的构造函数只能有一个
二 拷贝构造函数
创建对象时使用同类对象来进行初始化,这时所用的构造函数称为拷贝构造函数,拷贝构造函数是特殊的构造函数
特征如下:1.拷贝构造函数其实是一个构造函数的重载
2.拷贝构造函数的参数必须使用引用传参,使用传值方式会引发无穷递归调用(为什么)
原因:如果不传引用,那d1给d2进行传参数,先建一个临时对象,把参数传进去然后进行一系列赋值等,即实参是 形参临时拷贝即用的d1拷贝d,又要调用拷贝构造,依次下去无穷尽也。
3.若未显示定义,系统会默认缺省的拷贝构造函数,会依次拷贝类的数据成员完成初始化
三 析构函数
析构函数:与构造函数功能相反,在对象销毁时,由编译器自动调用,完成类的一些资源清理和汕尾工作
特征:1.析构函类名(构造函数名)加上字符~
2.析构函数无参数,无返回值
3.一个类有且只有一个析构函数,若未显示定义,系统会自动生成缺省的析构函数
4.在对象生命周期结束时,编译系统会自动调用析构函数
5.析构函数体内并不是删除对象(对象是在main函数中,对象的销毁是main函数栈帧干的事,而是做一些清理工 作)
四:赋值运算符重载
什莫是运算符重载呢?
为了增强程序的可读性,c++支持运算符重载
运算符重载的特征:
1.operator 合法的运算符 ,构成函数名
2.重载运算符以后,不能改变运算符的优先级/结合性/操作数个数
笔试题:五个c++不能重载的运算符 .* :: sizeof ?:(三目运算符) .(成员访问符)
底下附上原代码:
using namespace std;
class Date
{
public:Date(int year = 0, int month = 0, int day = 0)//构造
{
_year = year;
_day = day;
_month = month;
Date(const Date& d)//拷贝构造
{
cout << "拷贝构造" << endl;
_year = d._year;
_month = d._month;
_day = d._day;
}
Date& operator= (const Date& d)//如果返回值不用引用,返回临时变量,就要调一次拷贝构造函数
{ //如果参数不用引用,也要调用拷贝构造函数
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
}
{
cout << _year << " " << _month << " " << _day << endl;
}
private:
int _year;
int _month;
int _day;
int main()
{
Date d2(2017, 5, 6);
d2.Print();
Date d4;
d4 = d2;
d4.Print();
system("pause");
return 0;
}