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

探索C++賦值運算符重載的內部機制:手把手教你精通

這篇具有很好參考價值的文章主要介紹了探索C++賦值運算符重載的內部機制:手把手教你精通。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

探索C++賦值運算符重載的內部機制:手把手教你精通,C++,c++,開發(fā)語言


W...Y的主頁 ??

代碼倉庫分享???

探索C++賦值運算符重載的內部機制:手把手教你精通,C++,c++,開發(fā)語言


??前言:

探索C++賦值運算符重載的內部機制:手把手教你精通,C++,c++,開發(fā)語言

前一篇博客中我們已經了解并學習了初始化和清理模塊中的構造函數與析構函數,還有拷貝復制中的拷貝復制函數,它們都是類與對象中重要的成員,今天我們要來講一下拷貝復制模塊中另一個非常重要的內容——賦值重載,但是在學習賦值重載的同時我們應該先學習運算符重載,話不多說我們直接開始!

目錄

賦值運算符重載

運算符重載

?賦值運算符重載


賦值運算符重載

運算符重載

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

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	// Date(const Date& d) ?// 正確寫法
	void print()
	{
		cout << _year << '/' << _month << '/' << _day << endl;
	}
	Date(const Date& d) ?// 錯誤寫法:編譯報錯,會引發(fā)無窮遞歸
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	Date d2(2022,10,23);
	int x = 1; 
    int y = 2;
    bool ret = x > y;
	return 0;
}

探索C++賦值運算符重載的內部機制:手把手教你精通,C++,c++,開發(fā)語言?上圖是比較的反匯編代碼,我們可以看出編譯器可以直接做出運算符判斷。

一般情況下,我們去比較內置類型都非常容易去比較,因為內置類型都是一些基本變量int、char……我們可以直接使用運算符 ==、<、>等等去比較。但是自定義類型我們應該如何處理呢?

一般情況下我們可以自己創(chuàng)建一個比較函數進行比較:

//判斷前面日期是否比后面大
//大返回true,小返回false
bool Greater(Date x, Date y)
{
	if (x._year > y._year)
	{
		return true;
	}
	else if (x._year == y._year && x._month > y._month)
	{
		return true;
	}
	else if (x._year == y._year && x._month == y._month && x._day > y._day)
	{
		return true;
	}

	return false;
}

將此函數放入到類中才可以進行私有數據訪問,要不就將基本數據公有化!

上述函數可以輕松解決比大小的問題,但是還是有許多缺陷。比如:函數名的不規(guī)范就會導致我們不理解函數的作用。所以對于內置類型的比較C++針對起名字做出了一下規(guī)定:

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

注意:
不能通過連接其他符號來創(chuàng)建新的操作符:比如operator@
重載操作符必須有一個類類型參數
用于內置類型的運算符,其含義不能改變,例如:內置的整型+,不能改變其含義
作為類成員函數重載時,其形參看起來比操作數數目少1,因為成員函數的第一個參數為隱
藏的this

.* :: sizeof ?: . 注意以上5個運算符不能重載。這個經常在筆試選擇題中出現。?

那針對以上函數我們就可以這樣修改:

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

	return false;
}

在參數選擇時,我們選擇引用而不選擇直接傳參,這樣可以節(jié)約時間效率,不用調用拷貝構造函數。?

?這樣做我們用戶一眼就可以看出此函數的作用,是用來比大小的函數。但是這樣去調用函數時函數名還是太長了,而且不直白不美觀,所以我們在使用時可以使用非常簡單的方式進行調用:

bool ret1 = d1 > d2;

只需要一個運算符就可以調用此函數,是不是非常方便呢!編譯器可以幫助我們將這句話轉變?yōu)?,調用函數的語句。

注意:運算符重載與函數重載中都有重載二字,但是絕對是沒有任何關系的,函數重載是可以允許參數不同的同名函數,運算符重載是自定義類型可以直接使用運算符。不是姓“張”的都有血緣關系。

但是當我們萬事俱備之后進行編譯卻還是出現報錯:探索C++賦值運算符重載的內部機制:手把手教你精通,C++,c++,開發(fā)語言?這是為什么呢?

為什么會多一個參數呢?哪里多了?成員參數都會有一個隱藏的參數this指針。所以參數不匹配導致程序出問題。相當于我們在調用函數時使用了兩個參數,而設定的參數中卻有三個!

我們應該怎么解決問題呢?刪一個即可。

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	// Date(const Date& d) ?// 正確寫法
	void print()
	{
		cout << _year << '/' << _month << '/' << _day << endl;
	}
	//Date(const Date& d) ?// 錯誤寫法:編譯報錯,會引發(fā)無窮遞歸
	//{
	//	_year = d._year;
	//	_month = d._month;
	//	_day = d._day;
	//}
	bool 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;
	}

private:
	int _year;
	int _month;
	int _day;
};
//判斷日期是否相等
//bool Greater(Date x, Date y)
//bool Compare1(Date x, Date y)


int main()
{
	Date d1;
	Date d2(2022,10,23);
	/*d1 == d2;
	d1 > d2;*/
	bool ret1 = d1 > d2;
	int x = 1, y = 2;
	bool ret = x > y;
	return 0;
}

?我們將參數刪除一個即可,編譯器看就會轉換成d1.operator(d2)在進行轉換成d1.operator(&d1,d2)即可,地址就是this指針指向的內容。

我們學明白了運算符重載,那么在進行賦值運算符重載就非常easy了。

?賦值運算符重載

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

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

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

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;
};
// 賦值運算符重載成全局函數,注意重載成全局函數時沒有this指針了,需要給兩個參數
Date& operator=(Date& left, const Date& right)
{
if (&left != &right)
{
left._year = right._year;
left._month = right._month;
left._day = right._day;
}
return left;
}
// 編譯失?。?// error C2801: “operator =”必須是非靜態(tài)成員

原因:賦值運算符如果不顯式實現,編譯器會生成一個默認的。此時用戶再在類外自己實現
一個全局的賦值運算符重載,就和編譯器在類中生成的默認賦值運算符重載沖突了,故賦值
運算符重載只能是類的成員函數。探索C++賦值運算符重載的內部機制:手把手教你精通,C++,c++,開發(fā)語言?用戶沒有顯式實現時,編譯器會生成一個默認賦值運算符重載,以值的方式逐字節(jié)拷貝。注
意:內置類型成員變量是直接賦值的,而自定義類型成員變量需要調用對應類的賦值運算符
重載完成賦值

class Time
{
public:
Time()
{
_hour = 1;
_minute = 1;
_second = 1;
}
Time& operator=(const Time& t)
{
if (this != &t)
{
_hour = t._hour;
_minute = t._minute;
_second = t._second;
}
return *this;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
private:
// 基本類型(內置類型)
int _year = 1970;
int _month = 1;
int _day = 1;
// 自定義類型
Time _t;
};
int main()
{
Date d1;
Date d2;
d1 = d2;
return 0;
}

既然編譯器生成的默認賦值運算符重載函數已經可以完成字節(jié)序的值拷貝了,還需要自己實
現嗎?當然像日期類這樣的類是沒必要的。那么下面的類呢?驗證一下試試?

// 這里會發(fā)現下面的程序會崩潰掉?這里就需要我們以后講的深拷貝去解決。
typedef int DataType;
class Stack
{
public:
Stack(size_t capacity = 10)
{
_array = (DataType*)malloc(capacity * sizeof(DataType));
if (nullptr == _array)
{
perror("malloc申請空間失敗");
return;
}
_size = 0;
_capacity = capacity;
}
void Push(const DataType& data)
{
// CheckCapacity();
_array[_size] = data;
_size++;
}
~Stack()
{
if (_array)
{
free(_array);
_array = nullptr;
_capacity = 0;
_size = 0;
}
}
private:
DataType *_array;
size_t _size;
size_t _capacity;
};
int main()
{
Stack s1;
s1.Push(1);
s1.Push(2);
s1.Push(3);
s1.Push(4);
Stack s2;
s2 = s1;
return 0;
}

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

探索C++賦值運算符重載的內部機制:手把手教你精通,C++,c++,開發(fā)語言


以上就是賦值運算符重載全部內容?。?!感謝大家觀看。?文章來源地址http://www.zghlxwxcb.cn/news/detail-721251.html

到了這里,關于探索C++賦值運算符重載的內部機制:手把手教你精通的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

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

領支付寶紅包贊助服務器費用

相關文章

  • C++拷貝構造函數與賦值運算符重載

    C++拷貝構造函數與賦值運算符重載

    顧得泉: 個人主頁 個人專欄: 《Linux操作系統(tǒng)》?《C++從入門到精通》??《LeedCode刷題》 鍵盤敲爛,年薪百萬! ???????在現實生活中,可能存在一個與你一樣的自己,我們稱其為雙胞胎。 ???????那在創(chuàng)建對象時,可否創(chuàng)建一個與已存在對象一某一樣的新對象呢? ?

    2024年02月22日
    瀏覽(21)
  • 【C++】:拷貝構造函數和賦值運算符重載

    【C++】:拷貝構造函數和賦值運算符重載

    拷貝構造函數是特殊的構造函數。 是用一個已經存在的對象,賦值拷貝給另一個新創(chuàng)建的已經存在的對象 。 本質:用同類型的對象拷貝初始化 。 拷貝構造函數也是 特殊的成員函數 ,其特征如下: 2.1 拷貝構造函數是構造函數的一個重載形式。 2.2 拷貝構造函數的 函數名域

    2024年04月28日
    瀏覽(29)
  • C++修煉之筑基期第四層 ——透過日期類看運算符重載 | 賦值運算符重載 | 取地址操作符重載

    C++修煉之筑基期第四層 ——透過日期類看運算符重載 | 賦值運算符重載 | 取地址操作符重載

    ??作者簡介: 花想云 ,在讀本科生一枚,致力于 C/C++、Linux 學習。 ?? 本文收錄于 C++系列 ,本專欄主要內容為 C++ 初階、C++ 進階、STL 詳解等,專為大學生打造全套 C++ 學習教程,持續(xù)更新! ?? 相關專欄推薦: C語言初階系列 、 C語言進階系列 、 數據結構與算法 本章主要

    2023年04月09日
    瀏覽(21)
  • 【C++】類和對象(中)---拷貝構造函數、賦值運算符重載

    【C++】類和對象(中)---拷貝構造函數、賦值運算符重載

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

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

    C++ -3- 類和對象 (中) | 拷貝構造函數 & 賦值運算符重載

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

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

    【C++】:類和對象(中)之拷貝構造函數+賦值運算符重載

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

    2024年02月06日
    瀏覽(26)
  • c++類與對象(二)——賦值運算符重載與取地址操作符重載

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

    前言: 本章將通過 日期類 的實現,深入學習 運算符重載 的實現方法。本章將完成6個默認成員函數中剩余3個—— 賦值運算符重載 與 取地址操作符重載 的學習。 C++ 為了增強代碼的可讀性引入了 運算符重載 ,運算符重載是具有 特殊函數名 的函數,也具有其返回值類型,

    2024年02月03日
    瀏覽(21)
  • 【C++】C++入門—初識構造函數 , 析構函數,拷貝構造函數,賦值運算符重載

    【C++】C++入門—初識構造函數 , 析構函數,拷貝構造函數,賦值運算符重載

    如果一個類中什么成員都沒有,簡稱為空類。 空類中真的什么都沒有嗎? 并不是 任何類在什么都不寫時,編譯器會自動生成以下6個默認成員函數。 默認成員函數:用戶沒有顯式實現,編譯器會生成的成員函數稱為默認成員函數 我們實現了,編譯器就不會生成了 構造函數是

    2024年02月21日
    瀏覽(28)
  • C++從入門到精通——類的6個默認成員函數之賦值運算符重載

    C++從入門到精通——類的6個默認成員函數之賦值運算符重載

    類的6個默認成員函數:如果一個類中什么成員都沒有,簡稱為空類。 空類中真的什么都沒有嗎?并不是,任何類在什么都不寫時,編譯器會自動生成以下6個默認成員函數。 默認成員函數:用戶沒有顯式實現,編譯器會生成的成員函數稱為默認成員函數。 C++為了增強代碼的

    2024年04月25日
    瀏覽(30)
  • 【C++】類和對象③(類的默認成員函數:拷貝構造函數 | 賦值運算符重載)

    【C++】類和對象③(類的默認成員函數:拷貝構造函數 | 賦值運算符重載)

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

    2024年04月17日
    瀏覽(29)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包