关于类的6个默认成员函数


关于类的6个默认成员函数

一、前言知识

1.this指针
a.this指针式一个指针,它时时刻刻指向一个实例;
b.this指针的类型是:类类型* const;
c.this指针并不是对象本身的一部分,不影响sizeof的结果;
d.this指针是类成员函数的第一个默认隐含参数,编译器会自动维护和传递;

2.引用

a.引用不是新定义一个变量,而是给已存在的变量取了一个别名,所以编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间;

b.引用的格式:类型& 变量(对象名)=引用变量名

例如:int&ra=a;ara的类型相同。

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;
	}
};






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章