关于类的6个默认成员函数
一、前言知识
1.this指针
a.this指针式一个指针,它时时刻刻指向一个实例;
b.this指针的类型是:类类型* const;
c.this指针并不是对象本身的一部分,不影响sizeof的结果;
d.this指针是类成员函数的第一个默认隐含参数,编译器会自动维护和传递;
2.引用
a.引用不是新定义一个变量,而是给已存在的变量取了一个别名,所以编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间;
b.引用的格式:类型& 变量(对象名)=引用变量名;
例如:int&ra=a;a和ra的类型相同。
c.引用在定义时必须初始化;
d.一个变量可以有多个引用;
e.引用一旦绑定了一个实体,就不能再改变为其他变量的引用;
f.函数中不要返回栈内存的引用;
例如:int&Add(int& left,int& right)
{
int result=left+right;
return result;
}
g.使用引用可以起到和指针一样的作用,既可以改变实参的值,也可以改变形参的值。
二、类的六个成员函数
1.构造函数:是一个特殊的成员函数,名字与类名相同,创建类类型对象时,由编译器自动调用,在对象的生命周期内有且只调用一次,以保证每个数据成员都有一个合适的初始值。
#include<iostream>
using namespace std;
class Date
{
public:
Date()//第一种情况可以不传参数
{}
Date(int year, int month, int day)//第二种情况可以带参数
{}
Date(int year = 2017, int month = 2, int day = 18)//第三种情况是可以给参数带缺省值
{}
Date(int year, int month, int day)//第四种情况是给出初始化列表,初始化列表只有构造函数有
:_year = year
, _month = month
, _day = day
{}
private:
int _year;
int _month;
int _day;
};
构造函数的特点:
a.函数名与类名相同;
b.没有返回值;
c.有初始化列表,但是不强制使用;
e.新对象被创建时,由编译器自动调用,且在对象的生命周期内只调用一次;
f.构造函数可以重载,实参决定调用哪个构造函数;
g.引用数据成员、const数据成员、类类型成员必须要放在初始化列表中初始化;
h.explcit修饰构造函数,抑制由构造函数定义的隐式转换。
2.拷贝构造函数:只有单个形参,而且该形参是对本类类型对象的引用(常用const修饰),这样的构造函数称为拷贝构造函数。它是特殊的构造函数,创建对象时使用已存在的同类对象来进行初始化,由编译器自动调用。
#include<iostream>
using namespace std;
class Date
{
public:
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
private:
int _year;
int _month;
int _day;
};
拷贝构造函数的特点:
a.它是构造函数的重载;
b.它的参数必须使用同类类型对象的引用传递。
使用场景:a.对象实例化对象 b.传值方式作为函数的参数 c.传值方式作为函数返回值
3.析构函数:与构造函数功能相反,在对象被销毁时,由编译器自动调用,完成类的一些资源清理和汕尾工作。
形如:~Date()
{}
析构函数特点:
a.析构函数无参数无返回值;
b.一个类有且只有一个析构函数;
c.析构函数体内并不是删除对象,而是做一些清理工作。
4.赋值操作符重载函数
操作符重载函数形如:返回类型 operator 操作符(参数列表)
这里以一个Date类来说明:
#include<iostream>
using namespace std;
class Date
{
public:
bool JudgeLeapyear(int year)
{
if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)))
{
return true;
}
else
{
return false;
}
}
int GetDay(int year, int month)
{
int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (JudgeLeapyear(year) && (month == 2))
{
days[2] += 1;
}
return days[month];
}
Date(int year, int month, int day)
:_year(year)
, _month(month)
, _day(day)//初始化列表,只有构造函数才有
{
cout << "Date(int year, int month, int day)" << this << endl;
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
cout << "Date(const Date& d2)" << endl;
}
~Date()
{
cout << "~Date" << endl;
}
bool operator<(const Date& d)
{
return (_year < d._year) || ((_year == d._year) && (_month < d._month))
|| ((_year == d._year) && (_month == d._month) && (_day<d._day));
}
bool operator>(const Date& d)
{
return !((*this < d) || (*this == d));
}
bool operator<=(const Date& d)
{
return ((*this < d) || (*this == d));
//return !(*this>d);
}
bool operator>=(const Date& d)
{
return ((*this > d) || (*this == d));
//return !(*this<d);
}
bool operator==(const Date& d)
{
return (_year == d._year) && (_month == d._month) && (_day == d._day);
}
bool operator!=(const Date& d)
{
return !(*this == d);
}
Date operator+(int day)//求day天后的日期
{
Date temp(*this);
if (day < 0)
{
return ((*this) - (0 - day));
}
else
{
temp._day = temp._day + day;
if (temp._day>GetDay(temp._year, temp._month))
{
temp._day = temp._day - day;
if (temp._month == 12)
{
temp._year = temp._year + 1;
temp._month = 1;
}
else
{
temp._month++;
}
}
// else
//{
return temp;
//}
}
}
Date operator-(int day)//求day天前的日期
{
Date temp(*this);
if (day < 0)
{
return ((*this) + (0 - day));
}
else
{
temp._day = temp._day - day;
if (temp._day <= 0)
{
if (temp._month == 1)
{
temp._year = temp._year - 1;
temp._month = 12;
}
else
{
temp._month--;
}
temp._day = GetDay(temp._year, temp._month) - (0 - temp._day);
}
//else
// {
return temp;
// }
}
}
Date& operator++()//前置++
{
_day = _day + 1;
return *this;
}
Date& operator++(int)//后置++
{
Date temp(*this);
_day = _day + 1;
return *this;
}
Date& operator--()//前置--
{
_day = _day - 1;
return *this;
}
Date& operator--(int)//后置--
{
Date temp(*this);
_day = _day - 1;
return *this;
}
friend ostream& operator<< (ostream& out, const Date& d)
{
out << d._year << "--" << d._month << "--" << d._day << " " << endl;
return out;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2016, 1, 5);
Date d2(2015, 12, 20);
int result1 = d1<(d2);
int result2 = d1>(d2);
Date d3 = d1 + 10;
int result3 = d1 - d2;
Date d4 = d1++;
Date d5 = d1 + 1;
system("pause");
return 0;
}
5.取地址操作符重载
6.const修饰的取地址操作符重载
class CTest
{
public:
CTest* operator&()
{
return this;
}
const CTest* operator & ()const
{
return this;
}
};