亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語言運算符的重載詳解

 更新時間:2022年01月19日 09:20:49   作者:悲傷土豆拌飯  
大家好,本篇文章主要講的是C語言運算符的重載詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下

寫一個Add函數(shù)

我們先討論下面代碼,并復(fù)習(xí)前面的內(nèi)容

class Complex
{
private:
	double Real, Image;
public:
	Complex() :Real(0), Image(0) {}
	Complex(double r, double i) :Real(r), Image(i) {}
	~Complex() {}
	//Complex Add(const Complex* const this,const Complex &c)
	Complex Add(const Complex& x)const
	{
		Complex y;
		y.Real = Real + x.Real;
		y.Image = Image + x.Image;
		return y;
		//return Complex(this->Real + x.Real, this->Image + x.Image);
	}
	void Print()
	{
		cout << Real << "+" << Image << "i" << endl;
	}

};
int main()
{
	Complex c1(12, 23);
	Complex c2(4.5, 5.6);
	Complex c3;
	c3 = c1.Add(c2);
	c3.Print();

	return 0;
}

在這里插入圖片描述

直接return可以使用無名函數(shù)直接代替將亡值對象,相比可以省一次對象的構(gòu)建

我們再分析如果我們使用引用返回Add函數(shù)

const Complex& Add(const Complex& x)const
	{
		Complex y;
		y.Real = Real + x.Real;
		y.Image = Image + x.Image;
		return y;
		//return Complex(this->Real + x.Real, this->Image + x.Image);
	}

在這里插入圖片描述

若我們以引用返回,將亡值對象會創(chuàng)建在Add函數(shù)的棧幀中,然后返回將亡值地址,函數(shù)return結(jié)束該空間會被釋放、

若沒有引用,構(gòu)建無名對象也就是將亡值對象會構(gòu)建在主函數(shù)的空間中,這里使用將亡值對象值給到c3是沒有問題的

我們查看對象的構(gòu)造與析構(gòu)

class Complex
{
private:
	double Real, Image;
public:
	Complex() :Real(0), Image(0) {}
	Complex(double r, double i) :Real(r), Image(i) 
	{ 
		cout << "Create:" << this << endl; 
	}
	Complex(const Complex& x):Real(x.Real),Image(x.Image)
	{
		cout << "Copy Create:" << this << endl;
	}
	~Complex()
	{
		cout << "~Complex:" << this << endl;
	}
	//Complex Add(const Complex* const this,const Complex &c)
	Complex Add(const Complex& x)const
	{
		return Complex(this->Real + x.Real, this->Image + x.Image);
	}
	void Print()
	{
		cout << Real << "+" << Image << "i" << endl;
	}

};

int main()
{
	Complex c1(12, 23);
	Complex c2(4.5, 5.6);
	Complex c3;
	c3 = c1.Add(c2);
	c3.Print();

	return 0;
}

在這里插入圖片描述

首先我們使用引用返回需要加上const修飾,這是因為我們返回將亡值在臨時空間具有常性,所以普通引用是不能進行返回的,需要使用常引用返回

const Complex& Add(const Complex& x)const
{
	return Complex(this->Real + x.Real, this->Image + x.Image);
}

我們發(fā)現(xiàn)對臨時對象的構(gòu)建后馬上就進行析構(gòu),那么是怎么將數(shù)據(jù)拿出給到c3的?這個在最后我們進行分析

為什么不用加號作為函數(shù)名

//Complex operator+(const Complex* const this,const Complex &c)
Complex operator+(const Complex &c) const
{
	return Complex(this->Real + x.Real, this->Image + x.Image);
}

這里是不可以的,加號是一個操作符,不能使用操作放作為有效的函數(shù)名稱;但是在C++中為了使這些操作符號能夠當作函數(shù)名,那么我們需要在前面加上一個關(guān)鍵字operator

//Complex operator+(const Complex* const this,const Complex &c)
Complex operator+(const Complex &c) const
{
	return Complex(this->Real + x.Real, this->Image + x.Image);
}
也就是告訴編譯器,加號是一個有效的函數(shù)名,這就叫做運算符的重載;隨后我們之間使用 c3 = c1 + c2 就是可以的
int main()
{
	Complex c1(12, 23);
	Complex c2(4.5, 5.6);
	Complex c3;
	c3 = c1 + c2;
	//編譯器編譯會是下面的情況
	//c3 = c1.operator+(c2);
	//c3 = operator+(&c1,c2); 加上this指針
}

運算符的重載

一個對象,編譯器會給它有6個缺省函數(shù)

在這里插入圖片描述

我們再來看下面這個問題

//我們寫一個賦值運算符重載
void operator=(const Object& obj)
{
	this->value = obj.value;
}
//返回類型為void,這樣不可以就不可以連等
//obja = objb = objc;
//obja = objb.operator=(objc);
//obja = operator=(&objb,objc); 返回的無類型,不能給obja賦值

且賦值函數(shù)不可以定義為const修飾

Object& operator=(const Object& obj)
{
	this->value = obj.value;
	return *this;
}
obja = objb = objc;

//改寫
obja = objb.operator=(objc);
obja = operator=(&objb,objc);

obja.operator=(operator=(&objb,objc));
operator=(&obja,operator=(&objb,objc));

通過返回對象,就可以實現(xiàn)連等;并且我們可以通過引用返回,因為此對象的生存期并不受函數(shù)的影響,不會產(chǎn)生一個臨時對象作為一個過度

防止自賦值
若是我們將obja給obja賦值,也就是自賦值

obja = obja
operator=(&obja,obja);

我們就需要進行一步判斷

Object& operator=(const Object& obj)
{
	if(this != &obj)//防止自賦值
	{
		this->value = obj.value;
	}
	return *this;
}

上面問題解決

我們通過這段代碼來看,與上面問題相同

	Object& operator=(const Object& obj)
	{
		if (this != &obj)
		{
			this->value = obj.value;
		}
		return *this;
	}

};
Object& fun(const Object& obj)
{
	int val = obj.Value() + 10;
	Object obja(val);
	return obja;
}

int main()
{
	Object objx(0);
	Object objy(0);
	objy = fun(objx);
	cout << objy.Value() << endl;
	return 0;
}

我們在這里希望通過引用返回,這里return的臨時對象會構(gòu)建在fun函數(shù)的棧幀中,并且在函數(shù)結(jié)束棧幀釋放,隨后調(diào)用賦值運算符重載,但是數(shù)值依舊是正確的

在這里插入圖片描述

我們跟蹤這個被析構(gòu)對象的地址,首先我們定位在fun函數(shù)的return obja;,隨后進入析構(gòu)函數(shù)將我們的obja進行析構(gòu)

在這里插入圖片描述

接著運行到回到主函數(shù)進行賦值,接著進入賦值運算符重載,可以看到,這里的obj地址與已被析構(gòu)的obja地址相同

在這里插入圖片描述

在這里插入圖片描述

可以看到這個值依舊存在,依舊可以打印給出,這是因為vs2019的特殊性質(zhì)造成的;我們每次運行程序會發(fā)現(xiàn)每次的對象地址都在變化,邏輯地址會隨機改變,被析構(gòu)對象的棧幀不會被接下來的賦值運算符重載擾亂地址空間,所以即使我們引用返回的對象已經(jīng)死亡依舊可以將數(shù)值正確返回

但是在vc中,我們得到的值會是隨機值,這是因為vc中每次運行程序地址都不會改變,當我們從fun函數(shù)退出進入賦值語句中,就會將原本存儲數(shù)據(jù)的地址擾亂,繼而變成了隨機值

盡管我們引用返回能夠?qū)?shù)據(jù)正確打印,但是該對象已經(jīng)死亡,這是不安全的,所以我們一定不要以引用返回對象

在這里插入圖片描述

VS2019具有一個特點:當我們調(diào)用函數(shù),若函數(shù)中沒有定義局部變量或局部對象時,該函數(shù)基本不對棧幀進行清掃

總結(jié)

到此這篇關(guān)于C語言運算符的重載詳解的文章就介紹到這了,更多相關(guān)C語言運算符重載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)簡單的掃雷游戲(控制臺版)

    C++實現(xiàn)簡單的掃雷游戲(控制臺版)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)簡單的掃雷游戲,控制臺版的掃雷游戲希望大家喜歡,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • C++實現(xiàn)線性表順序存儲的示例代碼

    C++實現(xiàn)線性表順序存儲的示例代碼

    這篇文章主要為大家詳細介紹了C++實現(xiàn)線性表順序存儲的相關(guān)知識,文中的示例代碼講解詳細,具有一定的學(xué)習(xí)價值,感興趣的可以了解一下
    2023-03-03
  • 基于C語言實現(xiàn)簡單的掃雷游戲

    基于C語言實現(xiàn)簡單的掃雷游戲

    windows自帶的游戲《掃雷》是陪伴了無數(shù)人的經(jīng)典游戲,本文將利用C語言實現(xiàn)這一經(jīng)典的游戲,文中的示例代碼講解詳細,感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • c語言中abs()和fabs()的區(qū)別點整理

    c語言中abs()和fabs()的區(qū)別點整理

    在本篇文章里小編給大家分享的是關(guān)于c語言abs()和fabs()的區(qū)別,有需要的朋友們可以參考學(xué)習(xí)下。
    2020-02-02
  • C語言之格式化屏幕輸出詳解

    C語言之格式化屏幕輸出詳解

    這篇文章主要介紹了C語言之格式化屏幕輸出的相關(guān)資料,需要的朋友可以參考下,小編覺得這篇文章寫的還不錯,希望能夠給你帶來幫助
    2021-11-11
  • C++初始化列表學(xué)習(xí)

    C++初始化列表學(xué)習(xí)

    在C++中,struct和class的唯一區(qū)別是默認的克訪問性不同,而這里我們不考慮訪問性的問題,所以下面的代碼都以struct來演示
    2013-09-09
  • 超詳細的c語言字符串操作函數(shù)教程

    超詳細的c語言字符串操作函數(shù)教程

    字符串是一種重要的數(shù)據(jù)類型,有零個或多個字符組成的有限串行,下面這篇文章主要給大家介紹了關(guān)于c語言字符串操作函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 重啟后nvidia-smi命令不可執(zhí)行出現(xiàn)“Make?sure?that?the?latest?NVIDIA?driver?is?installed?and?running.”的問題解決

    重啟后nvidia-smi命令不可執(zhí)行出現(xiàn)“Make?sure?that?the?latest?NVIDIA?

    這篇文章主要介紹了重啟后nvidia-smi命令不可執(zhí)行,出現(xiàn)“Make?sure?that?the?latest?NVIDIA?driver?is?installed?and?running.”問題,本文給大家分享最新完美解決方法,需要的朋友可以參考下
    2022-12-12
  • C語言?auto和register關(guān)鍵字

    C語言?auto和register關(guān)鍵字

    這篇文章主要介紹了C語言?auto、register關(guān)鍵字,文章通過變量展開全文相關(guān)的詳細內(nèi)容,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-04-04
  • sizeof()的簡單介紹

    sizeof()的簡單介紹

    sizeof操作符以字節(jié)形式給出了其操作數(shù)的存儲大小
    2013-04-04

最新評論