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

c++類與對象(二)——賦值運(yùn)算符重載與取地址操作符重載

這篇具有很好參考價(jià)值的文章主要介紹了c++類與對象(二)——賦值運(yùn)算符重載與取地址操作符重載。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


前言:

本章將通過日期類的實(shí)現(xiàn),深入學(xué)習(xí)運(yùn)算符重載的實(shí)現(xiàn)方法。本章將完成6個(gè)默認(rèn)成員函數(shù)中剩余3個(gè)——賦值運(yùn)算符重載取地址操作符重載的學(xué)習(xí)。

一.運(yùn)算符重載

1.運(yùn)算符重載的概念

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

  • 函數(shù)名:關(guān)鍵字operator后面接需要重載的運(yùn)算符符號。
  • 函數(shù)原型
  • 返回值類型 operator操作符(參數(shù)列表)
  • bool operator==(Date d1,Date d2);

需要注意的是:

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

2.實(shí)現(xiàn)Date類

定義一個(gè)Date類:

class Date
{
public:
	//構(gòu)造函數(shù)
	Date(int year = 0, int month = 0, int day = 0)
	{
		//判斷日期是否合法
		//GetMonthDay()獲取這個(gè)月的天數(shù)
		if (month > 0 && month < 13 &&
			(day > 0 && day <= GetMonthDay(year, month)))
		{
				_year = year;
				_month = month;
				_day = day;
		}
		else
		{
			cout << "日期非法" << endl;
		}
	}
private:
	int _year;//年
	int _month;//月
	int _day;//日
};

函數(shù)接口:

// 類里面短小函數(shù),適合做內(nèi)聯(lián)的函數(shù),直接是在類里面定義的
class Date
{
	// 友元函數(shù)聲明
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);

public:
	// 構(gòu)造
	Date(int year = 0, int month = 0, int day = 0);
	void Print() const;
	// 當(dāng)月的天數(shù)
	int GetMonthDay(int year, int month) const;
	
	// 重載日期類與日期類運(yùn)算==, !=, <, <=, >, >=
	bool operator==(const Date& d) const;
	bool operator!=(const Date& d) const;
	bool operator<(const Date& d) const;
	bool operator<=(const Date& d) const;
	bool operator>(const Date& d) const;
	bool operator>=(const Date& d) const;
	
	// 重載日期類與天運(yùn)算+=, +, -=, -,
	Date& operator+=(int day);
	Date operator+(int day) const;
	Date& operator-=(int day);
	Date operator-(int day) const;

	// 重載日期類與日期類運(yùn)算-
	int operator-(const Date& d) const;
	
	// 賦值運(yùn)算符重載
	Date& operator=(const Date& d);

	// 重載日期類前置++--,后置++--
	Date& operator++();
	// int參數(shù) 僅僅是為了占位,跟前置重載區(qū)分
	Date operator++(int);
	Date& operator--();
	Date operator--(int);

	//取地址重載
	Date* operator&();
	const Date* operator&() const;

private:
	int _year;
	int _month;
	int _day;
};

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

inline istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

在實(shí)現(xiàn)運(yùn)算符重載的時(shí)候,有一點(diǎn)需要特別注意

二元運(yùn)算符的重載函數(shù)的參數(shù)有兩個(gè),規(guī)定第一個(gè)參數(shù)左操作數(shù),第二個(gè)參數(shù)右操作數(shù)。

在前面章節(jié)我們講過成員函數(shù)的特性,成員函數(shù)有一個(gè)自帶的參數(shù)this,類型為類類型。所以我們可以省略第一個(gè)參數(shù),只寫第二個(gè)參數(shù)。

所以:

(1)> < >= <= != 重載

先實(shí)現(xiàn)兩個(gè)運(yùn)算符重載函數(shù),其它的就可以復(fù)用已經(jīng)實(shí)現(xiàn)好的運(yùn)算符。

class Date
{
public:
	//構(gòu)造函數(shù)
	//...
	bool operator==(const Date& d)
	{
		return (_year == d._year) && (_month == d._month) && (_day == d._day);
	}
	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) 
	{
		//函數(shù)的復(fù)用
		return *this < d || *this == d;
	}

	bool operator>(const Date& d) 
	{
		//函數(shù)的復(fù)用
		return !(*this <= d);
	}

	bool operator>=(const Date& d) 
	{
		//函數(shù)的復(fù)用
		return !(*this < d);
	}

	bool operator!=(const Date& d) 
	{
		//函數(shù)的復(fù)用
		return !(*this == d);
	}
//...
};

(2)+= -= + - 重載

注意:下面四個(gè)運(yùn)算符重載的右操作數(shù)都為day天數(shù)

class Date
{
public:
	//...
	//獲取當(dāng)月的天數(shù)
	int GetMonthDay(int year, int month) 
	{
		assert(month > 0 && month < 13);

		int monthArray[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;
		}
		else
		{
			return monthArray[month];
		}
	}
	//+= 返回自身的引用,減少拷貝
	Date& operator+=(int day)
	{
		//判斷是否加了負(fù)數(shù)
		if (day < 0)
		{
			//復(fù)用
			*this -= -day;
			return *this;
		}

		_day += day;
		while (_day > GetMonthDay(_year, _month));
		{
			_day -= GetMonthDay(_year, _month);
			//進(jìn)位
			_month++;
			if (_month == 13)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}
	//-= 返回自身的引用,減少拷貝
	Date& operator-=(int day)
	{
		//判斷是否減了一個(gè)負(fù)數(shù)
		if (day < 0)
		{
			//復(fù)用
			*this += -day;
			return *this;
		}

		_day -= day;
		while (_day <= 0)
		{
			--_month;
			if (_month == 0)
			{
				--_year;
				_month = 12;
			}

			_day += GetMonthDay(_year, _month);
		}

		return *this;
	}
	Date operator+(int day) 
	{
		//拷貝構(gòu)造
		//因?yàn)榧硬桓淖冏陨淼闹?,所以?chuàng)建臨時(shí)對象
		Date tmp(*this);
		//復(fù)用
		tmp += day;
		return tmp;
	}
	Date operator-(int day)
	{
		Date tmp(*this);
		tmp -= day;
		return tmp;
	}
//...
};

(3)前置++與后置++重載

前置++與后置++都是一元運(yùn)算符,這二者的區(qū)別是:

  • 前置++++再使用返回++之后的數(shù)
  • 后置++先使用再++,返回++之前的數(shù)

為了能在重載的時(shí)候做出區(qū)分,·C++·規(guī)定:

  • 后置++重載時(shí)多增加一個(gè)int類型的參數(shù),但調(diào)用時(shí)該參數(shù)不用傳遞,編譯器會自動傳遞。
class Date
{
public:
	//...
	//前置++
	Date& operator++()
	{
		*this += 1;
		return *this;
	}
	//后置++
	// 注意:后置++是先使用后+1,因此需要返回+1之前的舊值,
	// 故需在實(shí)現(xiàn)時(shí)需要先將this保存一份,然后給this + 1
	// 而temp是臨時(shí)對象,因此只能以值的方式返回,不能返回引用
	Date operator++(int)
	{
		Date tmp(*this);
		*this += 1;
		return tmp;
	}
	//前置--
	Date& operator--()
	{
		*this -= 1;
		return *this;
	}
	//后置--
	Date operator--(int)
	{
		Date tmp(*this);
		*this -= 1;
		return tmp;
	}
//...
};

(4)日期-日期的實(shí)現(xiàn)

日期+日期沒有意義,但是日期-日期有意義,日期-日期代表兩日期相距多少天

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

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

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

		return n * flag;
	}
	//...
}

(5)<< 與 >>重載

Date d1(2023,5,1);
cout<<d1;
  1. <<>>是二元操作符,上文提到二元操作符第一個(gè)參數(shù)為左操作符,第二個(gè)參數(shù)為右操作符
  2. 因?yàn)轭愔谐蓡T函數(shù)第一個(gè)參數(shù)為this,所以左操作數(shù)就成了對象,右操作數(shù)變成了cout,這就成了d1<<cout,與平常使用的C++語法習(xí)慣不符,所以我們不能將<<>>寫到類的成員函數(shù)中,而是重載在類外面
  3. 但是類外的函數(shù)無法訪問類的私有函數(shù),所以我們將重載函數(shù)設(shè)置為友元函數(shù)來實(shí)現(xiàn)。
class Date
{
//...
	//申明友元函數(shù)
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
	//...
}
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日";
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

2.默認(rèn)成員函數(shù)——賦值運(yùn)算符重載

與之前的構(gòu)造函數(shù)析構(gòu)函數(shù)等默認(rèn)成員函數(shù)相同,賦值運(yùn)算符重載也是類的6個(gè)默認(rèn)成員函數(shù)之一。

賦值運(yùn)算符重載具有以下特性:

  1. 賦值運(yùn)算符重載格式:
    參數(shù)類型const &T,參數(shù)引用可以提高傳參效率
    返回值類型T&,返回值引用可以提高返回的效率,有返回值目的是為了支持連續(xù)賦值,檢測是否給自己連續(xù)賦值
    返回*this:要復(fù)合連續(xù)賦值的定義
  2. 賦值運(yùn)算符只能重載成類的成員函數(shù)不能重載成全局函數(shù);
class Date
{
//...
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
	//...
}

二.默認(rèn)成員函數(shù)——取地址操作符重載

6個(gè)默認(rèn)成員函數(shù)只剩兩個(gè)——取地址重載與const取地址重載。但是,這兩個(gè)函數(shù)實(shí)在沒有實(shí)現(xiàn)的必要,因?yàn)槲覀冏约簩?shí)現(xiàn)與編譯器自動實(shí)現(xiàn)出來的效果是一樣的。

class Date
{
	//...
	Date* operator&()
	{
		return this;
	}
	const Date* operator&()const
	{
		return this;
	}
	//...
};

#. 補(bǔ)充知識點(diǎn):const成員

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

例如:

class Date
{
public:
	//...
	void print()
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
}

void Test3()
{
	Date d1(2023, 4, 1);
	d1.print();
	const Date d2(2022, 3, 1);
	d2.print();
}

運(yùn)行結(jié)果:

c++類與對象(二)——賦值運(yùn)算符重載與取地址操作符重載
這是因?yàn)?strong>權(quán)限放大了:我們不能將const Date &d2傳遞給形參Date* this
正確寫法為:

void print() const
{
	cout << _year << "年" << _month << "月" << _day << "日" << endl;
}

無法顯示的修飾隱含參數(shù)*this,所以在函數(shù)后面加上const修飾。這樣做適合不在成員函數(shù)內(nèi)修改成員變量的函數(shù),對無const修飾的類同樣適用。


本文到此結(jié)束,碼文不易,還請多多支持哦!文章來源地址http://www.zghlxwxcb.cn/news/detail-438084.html

到了這里,關(guān)于c++類與對象(二)——賦值運(yùn)算符重載與取地址操作符重載的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【C++】類和對象(中)---拷貝構(gòu)造函數(shù)、賦值運(yùn)算符重載

    【C++】類和對象(中)---拷貝構(gòu)造函數(shù)、賦值運(yùn)算符重載

    個(gè)人主頁:平行線也會相交?? 歡迎 點(diǎn)贊?? 收藏? 留言? 加關(guān)注??本文由 平行線也會相交 原創(chuàng) 收錄于專欄【C++之路】?? 本專欄旨在記錄C++的學(xué)習(xí)路線,望對大家有所幫助??? 希望我們一起努力、成長,共同進(jìn)步。?? 拷貝構(gòu)造函數(shù),又稱復(fù)制構(gòu)造函數(shù),是一種特殊的

    2024年02月05日
    瀏覽(25)
  • C++ -3- 類和對象 (中) | 拷貝構(gòu)造函數(shù) & 賦值運(yùn)算符重載

    C++ -3- 類和對象 (中) | 拷貝構(gòu)造函數(shù) & 賦值運(yùn)算符重載

    示例: 拷貝初始化構(gòu)造函數(shù)的作用是將一個(gè)已知對象的數(shù)據(jù)成員值拷貝給正在創(chuàng)建的另一個(gè)同類的對象 無窮遞歸 ? Date(Date d){……} 首先,分析 傳值傳參的過程 傳引用傳參 : 沒有拷貝 的過程,直接傳 傳值傳參: 內(nèi)置類型 編譯器可以直接拷貝(淺拷貝/值拷貝——一個(gè)字節(jié)

    2023年04月19日
    瀏覽(27)
  • 【C++】:類和對象(中)之拷貝構(gòu)造函數(shù)+賦值運(yùn)算符重載

    【C++】:類和對象(中)之拷貝構(gòu)造函數(shù)+賦值運(yùn)算符重載

    在現(xiàn)實(shí)生活中,可能存在一個(gè)與你一樣的自己,我們稱其為雙胞胎 那在創(chuàng)建對象時(shí),可否創(chuàng)建一個(gè)與已存在對象一某一樣的新對象呢? 拷貝構(gòu)造函數(shù):只有單個(gè)形參,該形參是對本類類型對象的引用(一般常用const修飾),在用已存在的類類型對象創(chuàng)建新對象時(shí)由編譯器自動調(diào)

    2024年02月06日
    瀏覽(26)
  • [C++] 類與對象(中)完整講述運(yùn)算符重載示例 -- 日期類(Date) -- const成員

    [C++] 類與對象(中)完整講述運(yùn)算符重載示例 -- 日期類(Date) -- const成員

    ? 目錄 1、前言 2、全缺省的構(gòu)造函數(shù) 3、打印接口 4、拷貝構(gòu)造 5、賦值運(yùn)算符重載(operator=) 5.1賦值重載是默認(rèn)成員函數(shù),重載格式: 5.2 賦值重載不能為全局函數(shù) 5.3 編譯器默認(rèn)生成 6、析構(gòu)函數(shù) 7、operator 8、operator== 9、operator= 10、operator 11、operator= 12、operator!= 13、operato

    2024年02月13日
    瀏覽(24)
  • 【C++】類和對象③(類的默認(rèn)成員函數(shù):拷貝構(gòu)造函數(shù) | 賦值運(yùn)算符重載)

    【C++】類和對象③(類的默認(rèn)成員函數(shù):拷貝構(gòu)造函數(shù) | 賦值運(yùn)算符重載)

    ?? 個(gè)人主頁: Forcible Bug Maker ?? 專欄: C++ 目錄 前言 拷貝構(gòu)造函數(shù) 概念 拷貝構(gòu)造函數(shù)的特性及用法 賦值運(yùn)算符重載 運(yùn)算符重載 賦值運(yùn)算符重載 結(jié)語 本篇主要內(nèi)容:類的6個(gè)默認(rèn)成員函數(shù)中的 拷貝構(gòu)造函數(shù) 和 賦值運(yùn)算符重載 在上篇文章中我們講到了類的默認(rèn)成員函數(shù)的

    2024年04月17日
    瀏覽(29)
  • 【C++初階】四、類和對象(構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、賦值運(yùn)算符重載函數(shù))

    【C++初階】四、類和對象(構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、賦值運(yùn)算符重載函數(shù))

    ========================================================================= 相關(guān)代碼gitee自取 : C語言學(xué)習(xí)日記: 加油努力 (gitee.com) ?========================================================================= 接上期 : 【C++初階】三、類和對象 (面向過程、class類、類的訪問限定符和封裝、類的實(shí)例化、類對象模

    2024年02月05日
    瀏覽(32)
  • 【C++】詳解運(yùn)算符重載,賦值運(yùn)算符重載,++運(yùn)算符重載

    【C++】詳解運(yùn)算符重載,賦值運(yùn)算符重載,++運(yùn)算符重載

    目錄 前言 運(yùn)算符重載 概念 目的 寫法 調(diào)用 注意事項(xiàng) 詳解注意事項(xiàng) 運(yùn)算符重載成全局性的弊端 類中隱含的this指針 賦值運(yùn)算符重載 賦值運(yùn)算符重載格式 注意點(diǎn) 明晰賦值運(yùn)算符重載函數(shù)的調(diào)用 連續(xù)賦值 傳引用與傳值返回 默認(rèn)賦值運(yùn)算符重載 前置++和后置++重載 先梳理一下

    2024年04月25日
    瀏覽(32)
  • [C++] 類與對象(中)類中六個(gè)默認(rèn)成員函數(shù)(2)-- 運(yùn)算符重載 -- 取地址及const取地址操作符重載

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

    ? 本篇我們以日期類來展開講。對于一個(gè)日期,我們?nèi)绾稳ケ却笮∧??對年月日依次進(jìn)行比較可以,但是可以直接比較嗎? 我們可以看到,對于自定義類型的日期類直接去比較兩個(gè)日期的大小是錯誤的,因此我們需要對運(yùn)算符賦予特殊的功能,去實(shí)現(xiàn)可以對自定義類型的比較

    2024年02月13日
    瀏覽(34)
  • c++拷貝構(gòu)造與賦值運(yùn)算符重載

    c++拷貝構(gòu)造與賦值運(yùn)算符重載

    目錄 目錄: ? ? ? ? 1:拷貝構(gòu)造 ? ? ? ? 2:賦值運(yùn)算符重載 ???????? ? ? ? ? 前言:在上一章我們已經(jīng)學(xué)習(xí)過了,構(gòu)造與析構(gòu)這兩個(gè)默認(rèn)成員函數(shù)了,接下來讓我們一起來學(xué)習(xí)另外兩個(gè)重要的默認(rèn)成員函數(shù)。 ? ? ? ? 首先讓我們來講一下默認(rèn)成員函數(shù)這個(gè)概念,所謂

    2024年02月08日
    瀏覽(25)
  • C++奇跡之旅:深入理解賦值運(yùn)算符重載

    C++奇跡之旅:深入理解賦值運(yùn)算符重載

    運(yùn)算符重載是C++中的一個(gè)重要特性,他允許我們?yōu)樽远x的類型定義自己的運(yùn)算符行為。通過運(yùn)算符重載, 我們可以使用與內(nèi)置數(shù)據(jù)類型相同的語法來操作自定義類型,從而提高代碼的可讀性和可維護(hù)性 。 還是我們熟悉的日期函數(shù): 然后我們定義兩個(gè)日期對象d1和d2: 當(dāng)你想

    2024年04月26日
    瀏覽(20)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包