關於類的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;
	}
};






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