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

【C++初階】類和對象——操作符重載&&const成員函數(shù)&&取地址重載&&日期類的實現(xiàn)

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

=========================================================================

個人主頁點擊直達(dá):小白不是程序媛

C++系列專欄:C++頭疼記

=========================================================================

目錄?

前言:

運算符重載

運算符重載?

賦值運算符重載

前置++和后置++重載

const成員

取地址及const取地址操作符重載

使用函數(shù)操作符重載完成日期類的實現(xiàn)


前言:

上篇文章介紹了在C++的類六個成員函數(shù)中的三個,分別是構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù),不知道大家有沒有所收獲,今天我們帶來的是剩下的三個函數(shù),以及結(jié)合這六個函數(shù)完成一個完整的日期類的實現(xiàn),讓我們開始今天的征程吧!


運算符重載

在C++中有很多的運算符,包括 +、- 、* 、/、等等,一個兩兩結(jié)合的操作符++、--、+=,>=、==等等。

int main()
{
	int i = 0;
	cout << ++i << endl;
	cout << --i << endl;
	i = 2;
	cout << i << endl;
	return 0;
}

【C++初階】類和對象——操作符重載&&const成員函數(shù)&&取地址重載&&日期類的實現(xiàn),C++頭疼記,c++

對于內(nèi)置類型來說我們可以直接使用,但是對于我們自己定義的自定義類型呢?該如何使用呢?

  • 運算符重載?

C++為了增強代碼的可讀性引入了運算符重載,運算符重載是具有特殊函數(shù)名的函數(shù),也具有其
返回值類型,函數(shù)名字以及參數(shù)列表,其返回值類型與參數(shù)列表與普通的函數(shù)類似。

函數(shù)名字為:關(guān)鍵字operator后面接需要重載的運算符符號。
函數(shù)原型:返回值類型?operator操作符(參數(shù)列表)?

注意:

  • 不能通過連接其他符號來創(chuàng)建新的操作符:比如operator@
  • 重載操作符必須有一個類類型參數(shù)
  • 用于內(nèi)置類型的運算符,其含義不能改變,例如:內(nèi)置的整型+,不 能改變其含義
  • 作為類成員函數(shù)重載時,其形參看起來比操作數(shù)數(shù)目少1,因為成員函數(shù)的第一個參數(shù)為隱藏的this
  • .*? ::? sizeof? ?:? . 注意以上5個運算符不能重載。這個經(jīng)常在筆試選擇題中出現(xiàn)。

示例:==運算符重載

class Date
{
public:
	Date(int year = 1, int month = 1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Date& y)
	{
		return _year == y._year && _month == y._month && _day == y._day;
	}
private :
	int _year;
	int _month;
	int _day;
};
  • 賦值運算符重載

賦值運算符重載格式

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

class Date
{
public:
	Date(int year = 1, int month = 1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date& operator=(const Date& d)
	{
		this->_year = d._year;
		this->_month = d._month;
		this->_day = d._day;
		return *this;
	}
private :
	int _year;
	int _month;
	int _day;
};

賦值運算符只能重載成類的成員函數(shù)不能重載成全局函數(shù)

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	int _year;
	int _month;
	int _day;
};
// 賦值運算符重載成全局函數(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),編譯器會生成一個默認(rèn)的。此時用戶再在類外自己實現(xiàn)
一個全局的賦值運算符重載,就和編譯器在類中生成的默認(rèn)賦值運算符重載沖突了,故賦值
運算符重載只能是類的成員函數(shù)。【C++初階】類和對象——操作符重載&&const成員函數(shù)&&取地址重載&&日期類的實現(xiàn),C++頭疼記,c++

用戶沒有顯式實現(xiàn)時,編譯器會生成一個默認(rèn)賦值運算符重載,以值的方式逐字節(jié)拷貝。

注意:內(nèi)置類型成員變量是直接賦值的,而自定義類型成員變量需要調(diào)用對應(yīng)類的賦值運算符
重載完成賦值。

class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	Date(int year = 1, int month = 1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private :
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();
	Date d2 = d1;
	d2.Print();
	return 0;
}

【C++初階】類和對象——操作符重載&&const成員函數(shù)&&取地址重載&&日期類的實現(xiàn),C++頭疼記,c++

這里我們沒有寫賦值重載函數(shù),編譯器會自動生成一個完成操作,和拷貝構(gòu)造函數(shù)優(yōu)點類似。

注意:如果類中未涉及到資源管理,賦值運算符是否實現(xiàn)都可以;一旦涉及到資源管理則必
須要實現(xiàn)。

  • 前置++和后置++重載

class Date
{
public:
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	Date(int year = 1, int month = 1,int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	// 前置++:返回+1之后的結(jié)果
	// 注意:this指向的對象函數(shù)結(jié)束后不會銷毀,故以引用方式返回提高效率
	Date& operator++()
	{
		*this += 1;
		return *this;
	}
	// 后置++:
	// 前置++和后置++都是一元運算符,為了讓前置++與后置++形成能正確重載
	// C++規(guī)定:后置++重載時多增加一個int類型的參數(shù),但調(diào)用函數(shù)時該參數(shù)不用傳遞,編譯器自動傳遞
	// 注意:后置++是先使用后+1,因此需要返回+1之前的舊值,故需在實現(xiàn)時需要先將this保存一份,然后給this + 1
	// ???而temp是臨時對象,因此只能以值的方式返回,不能返回引用
	Date operator++(int)
	{
		Date tmp(*this);
		*this += 1;
		return tmp;
	}
private :
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1++;// 1-1-2
	++d1;// 1-1-1
	return 0;
}

const成員

將const修飾的“成員函數(shù)”稱之為const成員函數(shù),const修飾類成員函數(shù),實際修飾該成員函數(shù)
隱含的this指針,表明在該成員函數(shù)中不能對類的任何成員進行修改。
【C++初階】類和對象——操作符重載&&const成員函數(shù)&&取地址重載&&日期類的實現(xiàn),C++頭疼記,c++

我們來看看下面這段代碼?

class Date
{
public:
	//void Print( Date *this)
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};
int main()
{
	const Date d1;
	//d1.Print(&d1)
	//權(quán)限放大
	d1.Print();
	return 0;
}

這段代碼在編譯器上是編譯不通過的,說明語法有問題。

因為我們創(chuàng)建了一個const Date *的d1,將d1作為參數(shù)傳給函數(shù)時,函數(shù)的的參數(shù)是一個Date *,兩個參數(shù)不匹配,權(quán)限會放大,所以編譯不通過。

其實函數(shù)的形參就是this指針,那我們?nèi)绾螌his指針修飾為const呢?

只需要在函數(shù)聲明后面加上const 即可將this指針修飾為const。

class Date
{
public:
	//void Print( Date *this)
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};
int main()
{
	const Date d1;
	//d1.Print(&d1)
	//權(quán)限放大
	d1.Print();
	Date d2;
	d2.Print();
	return 0;
}

上面為修飾后的代碼,我們在創(chuàng)建一個普通的Date *,能否在const修飾的this指針函數(shù)中跑起來呢?

【C++初階】類和對象——操作符重載&&const成員函數(shù)&&取地址重載&&日期類的實現(xiàn),C++頭疼記,c++

答案是可以的,因為權(quán)限可以平移、縮小,不能放大。

那么請思考以下問題:

const對象可以調(diào)用非const成員函數(shù)嗎?

????????不可以,權(quán)限放大。
非const對象可以調(diào)用const成員函數(shù)嗎?

? ? ? ? 可以,權(quán)限縮小。
const成員函數(shù)內(nèi)可以調(diào)用其它的非const成員函數(shù)嗎?

? ? ? ? 不可以,權(quán)限放大。
非const成員函數(shù)內(nèi)可以調(diào)用其它的const成員函數(shù)嗎??

? ? ? ? 可以,權(quán)限縮小。


取地址及const取地址操作符重載

這兩個默認(rèn)成員函數(shù)一般不用重新定義 ,編譯器默認(rèn)會生成。

class Date
{
public:
	Date* operator&()
	{
		return this;
	}
	const Date* operator&()const
	{
		return this;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};

這兩個運算符一般不需要重載,使用編譯器生成的默認(rèn)取地址的重載即可,只有特殊情況,才需
要重載,比如想讓別人獲取到指定的內(nèi)容!?

這個函數(shù)基本沒有什么作用,很少用到作為了解即可!


使用函數(shù)操作符重載完成日期類的實現(xiàn)

void Date::Print()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}
//獲取天數(shù)
int Date::GetMonthDay(int year, int month)
{
	int monthArr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
	{
		return 29;
	}
	return monthArr[month];
}
//構(gòu)造函數(shù)
Date::Date(int year=1, int month=1, int day=1)
{
	_year = year;
	_month = month;
	_day = day;
}
//拷貝構(gòu)造函數(shù)
Date::Date(const Date& d)
{
	this->_year = d._year;
	this->_month = d._month;
	this->_day = d._day;
}
//賦值運算符重載
Date& Date::operator=(const Date& d)
{
	this->_year = d._year;
	this->_month = d._month;
	this->_day = d._day;
	return *this;
}
//日期+=天數(shù)
Date& Date::operator+=(int day)
{
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;
		if (_month == 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}
//日期+天數(shù)
Date Date::operator+(int day)
{
	Date tmp(*this);
	tmp += day;
	return *this;
}
//日期-=天數(shù)
Date& Date::operator-=(int day)
{
	_day -= day;
	while (_day <= 0)
	{
		//月小于0時應(yīng)該先借位
		--_month;
		if (_month == 0)
		{
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}
//日期-天數(shù)
Date Date::operator-(int day)
{
	Date tmp(*this);
	tmp -= day;
	return *this;
}
//前置++
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
//后置++
Date Date::operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp;
}
//前置--
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
//后置--
Date Date::operator--(int)
{
	Date tmp(*this);
	*this -= 1;
	return tmp;
}
//>運算符重載
bool Date::operator>(const Date& y)
{
	if (_year > y._year)
	{
		return true;
	}
	else if (_year == y._year && _month > y._month)
	{
		return true;
	}
	else if (_year == y._year && _month == y._month && _day > y._day)
	{
		return true;
	}
	return false;
}
//==運算符重載
bool Date::operator==(const Date& y)
{
	return _year == y._year && _month == y._month && _day == y._day;
}
//>=運算符重載
bool Date::operator>=(const Date& y)
{
	return *this > y || *this == y;
}
//<運算符重載
bool Date::operator<(const Date& y)
{
	return !(*this >= y);
}
//!=運算符重載
bool Date::operator!=(const Date& y)
{
	return !(*this == y);
}
//日期-日期 返回天數(shù)
int Date::operator-(const Date& y)
{
	Date max = *this;
	Date min = y;
	if (*this < y)
	{
		max = y;
		min = *this;
	}
	int n = 0;
	while (min != max)
	{
		min++;
		n++;
	}
	return n;
}

【C++初階】類和對象——操作符重載&&const成員函數(shù)&&取地址重載&&日期類的實現(xiàn),C++頭疼記,c++

這里我們使用操作符重載,完成了一個簡單的日期計算器,當(dāng)然這其中還有很多沒有完善的地方。像我們構(gòu)造一些非法的數(shù)據(jù)作為日期等等一些小問題,我就留給大家了。

C++類和對象(中)的六個成員函數(shù)就講完了,大家可以結(jié)合上篇文章細(xì)細(xì)閱讀,慢慢探索C++這六個成員函數(shù)的奧秘?,總結(jié)收獲出一些自己的東西。也希望大家留言指出我文章中出現(xiàn)的內(nèi)容,同時也感謝各位看官的三連支持,你們的支持就是我更新的動力!??!?


下篇預(yù)告:類和對象(下)文章來源地址http://www.zghlxwxcb.cn/news/detail-738757.html

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

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

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

相關(guān)文章

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包