国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】

這篇具有很好參考價值的文章主要介紹了【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、【C++】賦值運算符重載

1.1 運算符重載【引入】

  • C++為了增強代碼的可讀性引入了運算符重載,運算符重載是具有特殊函數(shù)名的函數(shù),也具有其返回值類型,函數(shù)名字以及參數(shù)列表,其返回值類型與參數(shù)列表與普通的函數(shù)類似。
  • 函數(shù)名字為:關(guān)鍵字operator后面接需要重載的運算符符號。
  • 函數(shù)原型:返回值類型 operator操作符(參數(shù)列表)

注意:

  • 不能通過連接其他符號來創(chuàng)建新的操作符:比如operator@

  • 重載操作符必須有一個類類型參數(shù)【不能去重載運算符改變內(nèi)置類型的行為】

  • 用于內(nèi)置類型的運算符,其含義不能改變,例如:內(nèi)置的整型+,不 能改變其含義

  • 作為類成員函數(shù)重載時,其形參看起來比操作數(shù)數(shù)目少1個,因為成員函數(shù)的第一個參數(shù)為隱藏的this

  • .* :: sizeof ?: . 注意以上5個運算符不能重載。這里的是.*,不是*,這寫經(jīng)常在筆試選擇題中出現(xiàn)。


  • 我們寫了一個日期類,有沒有可能要比較比較呢?
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//private: // 一會有解決方法
	int _year;
	int _month;
	int _day;
};

  • 我們寫了一個比較相等的函數(shù),如果是傳值的話沒有必要,我們形參直接寫成&,而且也不需要修改,所以再加上const
bool DateEquel(const Date& x, Date& y)
{
	return x._year == y._year
		&& x._month == y._month
		&& x._day == y._day;
}
  • 下面再實現(xiàn)一個函數(shù)【比較小于】
bool DateLess(const Date& x, Date& y)
{
	if (x._year < y._year)
	{
		return true;
	}
	else if(x._year == y._year)
	{
		if (x._month < y._month)
		{
			return true;
		}
		else if(x._month == y._month)
		{
			if (x._day < y._day)
			{
				return true;
			}
		}
	}
	return false;
}
  • 上面有一些不好的地方,取名字的問題,取得很亂就不知道這個函數(shù)是干什么的

下面我就要用一個新的符號

1.2 運算符重載

  • 這里的運算符重載函數(shù)重載的重載不是一個意思
  • 對運算符的行為重新定義

operator+運算符做函數(shù)名

  • 剛剛上面寫的代碼就可以寫成下面這樣
bool operator==(const Date& x, Date& y)
{
	return x._year == y._year
		&& x._month == y._month
		&& x._day == y._day;
} 
bool operator<(const Date& x, Date& y)
{
	if (x._year < y._year)
	{
		return true;
	}
	else if(x._year == y._year)
	{
		if (x._month < y._month)
		{
			return true;
		}
		else if(x._month == y._month)
		{
			if (x._day < y._day)
			{
				return true;
			}
		}
	}
	return false;
}
  • 就可以這樣使用了

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 還可以這樣做
  • 這里必須要加括號,因為流插入的優(yōu)先級很高

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 注意:參數(shù)不能反,左邊的操作數(shù)對應(yīng)的是左邊

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 我們再次回到上面,我們一開始是將內(nèi)置類型放開的

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 如果將他設(shè)置成私有,類外面就不能訪問了

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 我們這里有三種解決方法
  • 第一種就是在類里面搞一個Get函數(shù),這樣獲取【Java就是這樣做的】
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	int GetYear()
	{
		return _year;
	}

private:	
	int _year;
	int _month;
	int _day;
};
  • 第二種方法就是將函數(shù)放到類里面
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	bool operator==(const Date& x, Date& y)
	{
		return x._year == y._year
			&& x._month == y._month
			&& x._day == y._day;
	}

	bool operator<(const Date& x, Date& y)
	{
		if (x._year < y._year)
		{
			return true;
		}
		else if (x._year == y._year)
		{
			if (x._month < y._month)
			{
				return true;
			}
			else if (x._month == y._month)
			{
				if (x._day < y._day)
				{
					return true;
				}
			}
		}
		return false;
	}

private:	
	int _year;
	int _month;
	int _day;
};
  • 然后我們又發(fā)現(xiàn),函數(shù)的參數(shù)太多了,因為成員函數(shù)有一個隱含的this指針

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 下面進行修改
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	bool operator==(Date& y)
	{
		return _year == y._year
			&& _month == y._month
			&& _day == y._day;
	}

	bool operator<(Date& y)
	{
		if (_year < y._year)
		{
			return true;
		}
		else if (_year == y._year)
		{
			if (_month < y._month)
			{
				return true;
			}
			else if (_month == y._month)
			{
				if (_day < y._day)
				{
					return true;
				}
			}
		}
		return false;
	}

private:	
	int _year;
	int _month;
	int _day;
};
  • 我們使用就可以這樣使用了

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 我們通過查看反匯編再來了解一下

  • 首先看一下內(nèi)置類型的比較,是通過指令集的支持

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 再來看自定義類型
  • 可以看到兩種寫法的匯編代碼是一樣的,編譯器會先轉(zhuǎn)化,會一步到位的

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

1.3 賦值運算符重載

  • 我們接著寫日期類,下面寫一個賦值運算符
void operator=(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 但是我們寫的這個又遇到新的問題了,就是連續(xù)賦值是無法完成的

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 其實連續(xù)賦值就是右操作的返回值,做操作的值再進行賦值
  • 返回類型用傳引用返回,類型用引用,效率會提高Date&,返回的就是*this,不是this,這是個指針
Date& operator=(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;

	return *this;
}
  • 但是有可能有人這樣寫代碼:d1 = d1
d1 = d1
  • 這里我們就可以加上一個判斷,兩個相等的話直接返回即可

1.4 賦值

Date& operator=(const Date& d)
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}

  • 那么我們不寫這個賦值,編譯器不會不會自動生成一個呢?—>會的!

  • 因為這個是那6個默認成員函數(shù)之一

  • 內(nèi)置類型會值拷貝,自定義類型會調(diào)用它的拷貝

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

總結(jié):

  1. 賦值運算符重載格式
  • 參數(shù)類型:const T&,傳遞引用可以提高傳參效率
  • 返回值類型:T&,返回引用可以提高返回的效率,有返回值目的是為了支持連續(xù)賦值
  • 檢測是否自己給自己賦值
  • 返回*this :要復(fù)合連續(xù)賦值的含義

  1. 賦值運算符只能重載成類的成員函數(shù)不能重載成全局函數(shù)
  • 賦值運算符重載成全局函數(shù),注意重載成全局函數(shù)時沒有this指針了,需要給兩個參數(shù)
Date& operator=(Date& left, const Date& right)
{
	if (&left != &right)
	{
		left._year = right._year;
		left._month = right._month;
		left._day = right._day;
	}
	return left;
}

原因:賦值運算符如果不顯式實現(xiàn),編譯器會生成一個默認的。此時用戶再在類外自己實現(xiàn)一個全局的賦值運算符重載,就和編譯器在類中生成的默認賦值運算符重載沖突了,故賦值運算符重載只能是類的成員函數(shù)。

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

二、日期類的實現(xiàn)

  • 前面實現(xiàn)了一些邏輯,接下來我們就實現(xiàn)剩下的
  • 所有代碼在最后~~

2.1 判斷小于

  • 在上面已經(jīng)說明了,這里就直接寫出來了
bool operator<(const Date& d)
{
	if (_year < d._year)
	{
		return true;
	}
	else if (_year == d._year)
	{
		if (_month < d._month)
		{
			return true;
		}
		else if (_month == d._month)
		{
			if (_day < d._day)
			{
				return true;
			}
		}
	}
	return false;
}

2.2 判斷等于

  • 直接判斷相不相等
bool operator==(const Date& d)
{
	return _year == d._year
		&& _month == d._month
		&& _day == d._day;
}

2.3 判斷小于等于

  • 上面實現(xiàn)了小于,下面我們來實現(xiàn)一下小于等于
  • 既然上面都寫了小于和等于了,我們這里就可以直接復(fù)用
bool operator<=(const Date& d)
{
	return *this <= d || *this == d;
}

2.4 判斷大于

  • 這里的大于不就是小于等于的取反
bool operator>(const Date& d)
{
	return !(*this <= d);
}

2.5 判斷大于等于

  • 大于等于就是小于取反
bool operator>=(const Date& d)
{
	return !(*this < d);
}

2.6 判斷不等于

  • 不等于就是等于的取反
bool operator!=(const Date& d)
{
	return !(*this == d);
}

2.7 日期加等天數(shù)

2.8 獲取月份天數(shù)

  • 在實現(xiàn)日期加天數(shù)的時候我們需要再先實現(xiàn)一個獲取月份天數(shù)
  • 因為這里的獲取月份天數(shù)需要被頻繁調(diào)用,我們這里使用inline,可以不寫【在類內(nèi)聲明同時定義的成員函數(shù)自動轉(zhuǎn)化為內(nèi)聯(lián)函數(shù)】
  • 我們還將數(shù)組使用static修飾,避免了頻繁開辟
  • 然后再判斷閏年的時候我們把判斷月份放到了前面,首先判斷月份是否為2,為真繼續(xù)判斷下面的,否則每次都要執(zhí)行那么一長串的判斷閏年
inline int GetMonthDay(int year,int month)
{
	assert(month < 13 && month > 0);
	// 放到靜態(tài)區(qū)
	static int MonthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	// 先判斷月份
	if (month == 2 && (((year % 100 == 0) && (year % 4 == 0)) || (year % 400 != 0)))
		return 29;
	return MonthDays[month];
}
  • 然后繼續(xù)來實現(xiàn)
  • 首先加上天數(shù),然后判斷當前月的天數(shù)和加上的天數(shù)
  • 然后進行減掉天數(shù),月份+1,如果月份等于了13,年就+1,月份賦值為1
Date& operator+=(int day)
{
	// 這里就直接修改了
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;
		if (_month == 13)
		{
			++_year;
			_month = 1;
		}
	}
	return *this;
}

2.9 日期加天數(shù)

  • 上面是實現(xiàn)了+=,+也就很好實現(xiàn)了,這里只需要另外開一塊空間,修改別的空間就不會影響我這里的值
  • 這里不可以用引用返回,tmp是一個臨時對象,必須用傳值返回
Date operator+(int day)
{
	Date tmp(*this);
	tmp._day += day;
	while (tmp._day > GetMonthDay(tmp._year, tmp._month))
	{
		tmp._day -= GetMonthDay(tmp._year, tmp._month);
		++tmp._month;
		if (tmp._month == 13)
		{
			++tmp._year;
			tmp._month = 1;
		}
	}
	return tmp;
}
  • 上面那個+和+=的代碼相似,我們也可以復(fù)用一下
Date operator+(int day)
{
	Date tmp(*this);
	tmp += day;
	return tmp;
}

  • 上面的代碼是+復(fù)用+=,那么我們也可以用+=復(fù)用+
Date& operator+=(int day)
{
	*this = *this + day;
	return *this;
}

  • 那么這兩種寫法哪一種比較好呢?

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 這里左邊的更好,右邊的會復(fù)用+,而+里面會創(chuàng)建臨時對象

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

2.9.1 日期減等天數(shù)

  • 經(jīng)過上面的思考,我們先實現(xiàn)減等
Date& operator-=(int day)
{
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			--_year;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

2.9.2 日期減天數(shù)

Date operator-(int day)
{
	Date tmp = *this;
	tmp -= day;

	return tmp;
}

三、前置++ && 后置++

  • 前置++很簡單
Date& operator++()
{
	*this += 1;
	return *this;
}
  • 后置++要返回++后的值【這里要注意,后置++的操作符是有一個**(int)區(qū)分的**】
  • 后置++相比前置++的效率是低一些的
Date operator++(int)
{
	Date tmp = *this;
	*this += 1;
	return tmp;
}

3.1 日期減日期【返回天數(shù)】

int operator-(const Date& d)
{
	int flag = 1;
	Date max = *this;
	Date min = d;
	if (*this < d)
	{
		int flag = -1;
		max = d;
		min = *this;
	}
	// 相差天數(shù)
	int n = 0;
	while (min != max)
	{
		++min;
		++n;
	}
	return n * flag;
}

3.2 流插入

  • 對于內(nèi)置類型可以流插入,那么內(nèi)置類型也可以流插入

  • 對于流插入【cout】,對于庫里面全局的ostream類型的對象 -->點我

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 這里我們在使用的時候就反了,第一個被this占用了
void operator<<(ostream& out)
{
	out << _year << "年" << _month << "月" << _day << "日" << endl;
}
  • 作為成員函數(shù)重載,this指針占據(jù)第一個參數(shù),Date必須是在操作數(shù)

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 所以我們就必須讓ostream占據(jù)第一個位置

  • 想要占據(jù)第一個參數(shù),就不能寫成成員函數(shù),就要寫成全局函數(shù)

  • 當我們寫成全局函數(shù)的時候,·不能訪問類的私有了,這里也要后面的友元

void operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
}
  • 這里想要改成多個插入,我們返回值就要改一下
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

3.3 流提取

  • 流提取是cin

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 這里就不能使用const了
istream& operator>>(istream& in, Date& d)
{
	cout << "請依次輸入年月日:>";
	in >> d._year >> d._month >> d._day;
	return in;
}

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

3.4 檢查輸入日期是否合法

bool CheckInvalid()
{
	if (_year <= 0
		|| _month < 1
		|| _month > 12
		|| _day < 1
		|| _day > GetMonthDay(_year,_month))
	{
		return false;
	}
	else
	{
		return true;
	}
}
  • 這個時候把可以改檢查的地方就檢查一下

四、日期類的實現(xiàn)【源碼】

#include <iostream>
#include <assert.h>
using namespace std;

class Date
{
public:
	// 構(gòu)造函數(shù)
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;

		if (!CheckInvalid())
		{
			cout << "構(gòu)造日期非法" << endl;
		}
	}
	// 判斷等于
	bool operator==(const Date& d)
	{
		return _year == d._year
			&& _month == d._month
			&& _day == d._day;
	}
	// 判斷小于
	bool operator<(const Date& d)
	{
		if (_year < d._year)
		{
			return true;
		}
		else if (_year == d._year)
		{
			if (_month < d._month)
			{
				return true;
			}
			else if (_month == d._month)
			{
				if (_day < d._day)
				{
					return true;
				}
			}
		}
		return false;
	}
	// 判斷小于等于
	bool operator<=(const Date& d)
	{
		return *this <= d || *this == d;
	}
	// 判斷大于
	bool operator>(const Date& d)
	{
		return !(*this <= d);
	}
	// 判斷大于等于
	bool operator>=(const Date& d)
	{
		return !(*this < d);
	}
	// 判斷不等于
	bool operator!=(const Date& d)
	{
		return !(*this == d);
	}
	// 日期加等天數(shù)

	Date& operator+=(int day)
	{
		_day += day;
		while (_day > GetMonthDay(_year, _month))
		{
			_day -= GetMonthDay(_year, _month);
			++_month;
			if (_month == 13)
			{
				++_year;
				_month = 1;
			}
		}
		return *this;
	}

	Date operator+(int day)
	{
		Date tmp(*this);
		//Date tmp = *this;
		tmp += day;
		return tmp;
	}

	// 日期加天數(shù)
	Date operator+(const Date& d)
	{
		Date tmp(*this);
		tmp._day += d._day;
		while (d._day > GetMonthDay(tmp._year, tmp._month))
		{
			tmp._day -= GetMonthDay(tmp._year, tmp._month);
			++tmp._month;
			if (tmp._month == 13)
			{
				++tmp._year;
				tmp._month = 1;
			}
		}
		return tmp;
	}

	// 日期-=天數(shù)
	Date& operator-=(int day)
	{
		_day -= day;
		while (_day <= 0)
		{
			--_month;
			if (_month == 0)
			{
				--_year;
				_month = 12;
			}
			_day += GetMonthDay(_year, _month);
		}
		return *this;
	}

	// 日期減天數(shù)
	Date operator-(int day)
	{
		Date tmp = *this;
		tmp -= day;

		return tmp;
	}

	// 前置++
	Date& operator++()
	{
		*this += 1;
		return *this;
	}

	// 后置++
	Date operator++(int)
	{
		Date tmp = *this;
		*this += 1;

		return tmp;
	}

	// 日期-日期
	int operator-(const Date& d)
	{
		int flag = 1;
		Date max = *this;
		Date min = d;

		if (*this < d)
		{
			int flag = -1;
			max = d;
			min = *this;
		}

		int n = 0;
		while (min != max)
		{
			++min;
			++n;
		}
		return n * flag;
	}


	// 獲取月份天數(shù)[可以不寫inline,類里默認就是]
	inline int GetMonthDay(int year, int month)
	{
		assert(month < 13 && month > 0);
		// 放到靜態(tài)區(qū)
		static int MonthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		// 先判斷月份
		if (month == 2 && (((year % 100 == 0) && (year % 4 == 0)) || (year % 400 != 0)))
			return 29;
		return MonthDays[month];
	}

	// 拷貝構(gòu)造
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);

	bool CheckInvalid()
	{
		if (_year <= 0
			|| _month < 1
			|| _month > 12
			|| _day < 1
			|| _day > GetMonthDay(_year,_month))
		{
			return false;
		}
		else
		{
			return true;
		}
	}

	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	while (1)
	{
		cout << "請依次輸入年月日:>";
		in >> d._year >> d._month >> d._day;

		if (!d.CheckInvalid())
		{
			cout << "輸入非法日期,請重新輸入" << endl;
		}
		else
		{
			break;
		}
	}
	return in;
}

五、const修飾

5.1 const成員函數(shù)

  • 將const修飾的“成員函數(shù)”稱之為const成員函數(shù),const修飾類成員函數(shù),實際修飾該成員函數(shù)隱含的this指針,表明在該成員函數(shù)中不能對類的任何成員進行修改。

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 我們看下面這段代碼
class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "Print()" << endl;
		cout << "year:" << _year << endl;
		cout << "month:" << _month << endl;
		cout << "day:" << _day << endl << endl;
	}
	void Print()
	{
		cout << "Print()const" << endl;
		cout << "year:" << _year << endl;
		cout << "month:" << _month << endl;
		cout << "day:" << _day << endl << endl;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};
  • 這里會出現(xiàn)一個權(quán)限放大的問題

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 那么在參數(shù)就需要改成const Date*

  • 為了解決這個問題,我們就要在函數(shù)后面的位置加上一個const

  • 修飾的是this指針指向的內(nèi)容

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 那么不是下面方法調(diào)用也是可以的,因為這個是權(quán)限的縮小

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • const對象可以調(diào)用,非const對象也可以調(diào)用

  • 那么全部函數(shù)都可以加上const嗎?—>不可以!
  • 如果函數(shù)內(nèi)部要被修改,那肯定是不能加的
  • 上面寫的日期類的部分函數(shù)也可以加上~~

5.2 小結(jié)一下:

  • 成員函數(shù)如果是一個對成員變量只進行訪問的函數(shù),建議加上const,這樣const對象和非const對象都可以訪問

  • 成員函數(shù)如果是一個對成員變量進行讀寫訪問的函數(shù),不可以加上const,否則不能修改成員變量

  1. const對象可以調(diào)用非const成員函數(shù)嗎? --> 不可以!【權(quán)限放大】
  2. 非const對象可以調(diào)用const成員函數(shù)嗎?–> 可以!【權(quán)限縮小】
  3. const成員函數(shù)內(nèi)可以調(diào)用其它的非const成員函數(shù)嗎?–> 不可以!【權(quán)限放大】
  4. 非const成員函數(shù)內(nèi)可以調(diào)用其它的const成員函數(shù)嗎?–> 可以!【權(quán)限縮小】

5.3 默認成員函數(shù)【取地址及const取地址操作符重載】

  • 前面章節(jié)學(xué)習了4個默認成員函數(shù)了,剩下兩個再看一下

【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】,C++,c++,c,運算符重載

  • 這兩個默認成員函數(shù)一般不用重新定義 ,編譯器默認會生成。
class Date
{
public:
	Date* operator&()
	{
		return this;
	}
	const Date* operator&()const
	{
		return this;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};
  • 比如說不想讓別人拿到我的地址,普通對象返回空,const對象返回假地址
  • 就可以這樣寫:
Date* operator&()
{
	return nullptr;
}
const Date* operator&()const
{
	int i = 0;
	return (const A*)&i;
}
  • 這兩個運算符一般不需要重載,使用編譯器生成的默認取地址的重載即可,只有特殊情況,才需要重載,比如想讓別人獲取到指定的內(nèi)容!

最后本文主要學(xué)習了運算符重載這個知識點,并且在學(xué)習的時候?qū)崿F(xiàn)了一個日期類,望烙鐵們學(xué)有所成~~文章來源地址http://www.zghlxwxcb.cn/news/detail-833145.html

到了這里,關(guān)于【C++】中類的6個默認成員函數(shù) 取地址及const成員函數(shù) && 學(xué)習運算符重載 && 【實現(xiàn)一個日期類】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【C++初階】五、類和對象(日期類的完善、流運算符重載函數(shù)、const成員、“&”取地址運算符重載)

    【C++初階】五、類和對象(日期類的完善、流運算符重載函數(shù)、const成員、“&”取地址運算符重載)

    ========================================================================= 相關(guān)代碼gitee自取 : C語言學(xué)習日記: 加油努力 (gitee.com) ?========================================================================= 接上期 : 【C++初階】四、類和對象 (構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、賦值運算符重載函數(shù))-CSD

    2024年02月05日
    瀏覽(37)
  • [C++] 類與對象(中)類中六個默認成員函數(shù)(2)-- 運算符重載 -- 取地址及const取地址操作符重載

    [C++] 類與對象(中)類中六個默認成員函數(shù)(2)-- 運算符重載 -- 取地址及const取地址操作符重載

    ? 本篇我們以日期類來展開講。對于一個日期,我們?nèi)绾稳ケ却笮∧兀繉δ暝氯找来芜M行比較可以,但是可以直接比較嗎? 我們可以看到,對于自定義類型的日期類直接去比較兩個日期的大小是錯誤的,因此我們需要對運算符賦予特殊的功能,去實現(xiàn)可以對自定義類型的比較

    2024年02月13日
    瀏覽(34)
  • C++類的默認成員函數(shù)

    C++類的默認成員函數(shù)

    什么是默認函數(shù)? 默認函數(shù)就是當你使用這個類對象時,這個類會自動調(diào)用的函數(shù)C++中有六個默認成員函數(shù),并且作用各不相同,下面我們來一一進行介紹 什么是構(gòu)造函數(shù)?構(gòu)造函數(shù)是干什么的? 什么是析構(gòu)函數(shù)?析構(gòu)函數(shù)是干什么的? 我們以棧為例,每一次我們在使用棧的時

    2024年02月02日
    瀏覽(24)
  • 【C++】類的默認成員函數(shù)(下)

    【C++】類的默認成員函數(shù)(下)

    ?? 博客主頁 : 小羊失眠啦. ?? 系列專欄 : 《C語言》 《數(shù)據(jù)結(jié)構(gòu)》 《C++》 《Linux》 《Cpolar》 ?? 感謝大家點贊??收藏?評論?? 本章主要內(nèi)容為認識與學(xué)習C++非常重要的概念—— 運算符重載 。通過 日期類 的實現(xiàn),逐步學(xué)習各個運算符重載的實現(xiàn)方法即含義。6個默

    2024年03月18日
    瀏覽(28)
  • C++:類的六個默認成員函數(shù)

    C++:類的六個默認成員函數(shù)

    個人主頁 : 個人主頁 個人專欄 : 《數(shù)據(jù)結(jié)構(gòu)》 《C語言》《C++》 本篇博客作為C++知識總結(jié),我們來認識類的六個默認成員函數(shù)。 下面我主要以日期類作為示例顯示。 構(gòu)造函數(shù) 是一個特殊的成員函數(shù),名字與類名相同,創(chuàng)建類類型對象時(實例化類)由編譯器自動調(diào)用,以保

    2024年02月08日
    瀏覽(18)
  • 【C++】類和對象(中)---取地址及const取地址操作符重載、const成員函數(shù)的使用

    【C++】類和對象(中)---取地址及const取地址操作符重載、const成員函數(shù)的使用

    個人主頁:平行線也會相交?? 歡迎 點贊?? 收藏? 留言? 加關(guān)注??本文由 平行線也會相交 原創(chuàng) 收錄于專欄【C++之路】?? 本專欄旨在記錄C++的學(xué)習路線,望對大家有所幫助??? 希望我們一起努力、成長,共同進步。?? 今天是521,先祝各位玩的開心哈?。?! 前面已經(jīng)更

    2024年02月08日
    瀏覽(25)
  • 【C++】類和對象②(類的默認成員函數(shù):構(gòu)造函數(shù) | 析構(gòu)函數(shù))

    【C++】類和對象②(類的默認成員函數(shù):構(gòu)造函數(shù) | 析構(gòu)函數(shù))

    ?? 個人主頁: Forcible Bug Maker ?? 專欄: C++ 目錄 前言 類的6個默認成員函數(shù) 構(gòu)造函數(shù) 概念 構(gòu)造函數(shù)的特性及用法 析構(gòu)函數(shù) 概念 析構(gòu)函數(shù)的特性及用法 結(jié)語 本篇主要內(nèi)容:類的6個默認成員函數(shù)中的 構(gòu)造函數(shù) 和 析構(gòu)函數(shù) 進入到類和對象內(nèi)容的第二節(jié),上篇博客中介紹了

    2024年04月16日
    瀏覽(37)
  • C++從入門到精通——類的6個默認成員函數(shù)之拷貝構(gòu)造函數(shù)

    C++從入門到精通——類的6個默認成員函數(shù)之拷貝構(gòu)造函數(shù)

    類的6個默認成員函數(shù):如果一個類中什么成員都沒有,簡稱為空類。 空類中真的什么都沒有嗎?并不是,任何類在什么都不寫時,編譯器會自動生成以下6個默認成員函數(shù)。 默認成員函數(shù):用戶沒有顯式實現(xiàn),編譯器會生成的成員函數(shù)稱為默認成員函數(shù)。 在現(xiàn)實生活中,可

    2024年04月26日
    瀏覽(22)
  • 【C++初階】第三站:類和對象(中) -- 類的6個默認成員函數(shù)

    【C++初階】第三站:類和對象(中) -- 類的6個默認成員函數(shù)

    目錄 前言 類的6個默認成員函數(shù) 構(gòu)造函數(shù) 概念 特性 析構(gòu)函數(shù)? 概念 特性 拷貝構(gòu)造函數(shù) 概念 特征 賦值運算符重載 運算符重載 賦值運算符重載 const成員 const修飾類成員函數(shù) 取地址及const取地址操作符重載 本章總結(jié): ????????有時候我們寫好了一個棧,頭腦中第一件事

    2024年02月20日
    瀏覽(25)
  • C++ 類和對象篇(八) const成員函數(shù)和取地址運算符重載

    C++ 類和對象篇(八) const成員函數(shù)和取地址運算符重載

    目錄 一、const成員函數(shù) 1. const成員函數(shù)是什么? 2. 為什么有const成員函數(shù)? 3. 什么時候需要使用const修飾成員函數(shù)?? 二、取地址運算符重載 1. 為什么需要重載取地址運算符? 2. 默認取地址運算符重載函數(shù) 3.?默認const取地址運算符重載函數(shù) 4. 什么時候要顯示重載取地址運算

    2024年02月07日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包