欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中的運(yùn)算符重載詳解

 更新時(shí)間:2022年01月20日 16:10:14   作者:看書就頭疼  
大家好,本篇文章主要講的是C++中的運(yùn)算符重載詳解,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下

1、引例

class Complex
{
private:
    double Real,Image;
public:
    Complex():Real(0),Image(0)  {}
    Complex(double r, double i) : Real(r),Image(i) {}
    ~Complex()  {}
};

int main()
{
    Complex c1(1.2,2.3);
    Complex c2(45,56);

    Complex c3;
    c3 = c1.Add(c2);        
   
}

類非常簡(jiǎn)單,下面我們要討論如何寫一個(gè)Add函數(shù),使得兩個(gè)對(duì)象的屬性相加,返回一個(gè)新的對(duì)象。

第一種:

Complex::Complex Add(const Complex &c)
{
    Complex co;
    co.Real = this->Real + c.Real;
    co.Image = this->Image + c.Image;
    return co;
}

問題1:如何寫出最節(jié)省空間的Add函數(shù)?

第二種:

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

由于不需要改變調(diào)用對(duì)象的屬性值,我們給this指針添加const 修飾。

分析過程如下:

在這里插入圖片描述

問題2:為什么第一種方式不節(jié)省空間呢?

首先第一種的代碼比較繁瑣,并且在函數(shù)棧幀中又創(chuàng)建了一個(gè)對(duì)象(第3行)。并且函數(shù)類型是值傳遞類型(第6行),返回的是一個(gè)將亡值對(duì)象。那么整個(gè)Add函數(shù)空間會(huì)產(chǎn)生兩個(gè)對(duì)象,造成空間的浪費(fèi)。

第二中代碼創(chuàng)建的是無名對(duì)象,減少了一個(gè)co對(duì)象的創(chuàng)建,并且將無名對(duì)象直接作為將亡值對(duì)象傳遞給main函數(shù)中的c3。

問題3:我們能否將Add函數(shù)改為引用類型,這樣來減少將亡值對(duì)象的創(chuàng)建

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

VS2019發(fā)現(xiàn)報(bào)錯(cuò),不能返回引用對(duì)象:

在這里插入圖片描述

我們進(jìn)行分析:

在這里插入圖片描述

問題4:我們能否將這個(gè)Add函數(shù)名改為 + 運(yùn)算符?

//Complex::Complex Add(const Complex &c) const
Complex::Complex +(const Complex &c) const 
{
	Complex co;
	co.Real = this->Real + c.Real;
	co.Image = this->Image + c.Image;
	return co;
}

int main()
{
    ...
    //c3 = c1.Add(c2);  
    c3 = c1.+(c2);    //將原先Add的地方改變?yōu)榧犹?hào)。
    ...
}
	        

這樣使用,編譯器又會(huì)報(bào)錯(cuò),操作符不可作為一個(gè)有效的函數(shù)名來被使用。

問題5:如何使 +預(yù)算符 作為函數(shù)名使用?

這就引出了今天的關(guān)鍵,函數(shù)運(yùn)算符重載。

在C++中,為了使操作符作為一個(gè)有效的函數(shù)名,我們在操作符前面添加一個(gè)operator。

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

int main()
{
     Complex c1(1.2,2.3);
     Complex c2(10,10);
     Complex c3;
     c3 = c1 + c2;
    
     //上面一行實(shí)際上是
     //c3 = c1.operator+ (c2);
     //c3 = operator+(&c1,c2);  //編譯器還會(huì)經(jīng)過一次編譯
}

前面幾篇博客已經(jīng)分析了第15行的由來,是將c1的地址傳遞給this指針,將c2作為形參c的別名傳遞給函數(shù)。

2、類中自動(dòng)建立的函數(shù)

在C++中,如果我們定義一個(gè)類,它會(huì)給我們自動(dòng)創(chuàng)建六個(gè)缺省函數(shù)

構(gòu)造函數(shù)析構(gòu)函數(shù)拷貝構(gòu)造函數(shù)賦值函數(shù)普通對(duì)象的&(取地址符)的重載常對(duì)象的&(取地址符)重載

代碼示例如下:

class Object
{
public:
    Object()    {}							//構(gòu)造函數(shù)
    ~Object()   {}							//析構(gòu)函數(shù)
    Object(const Object &obj)   {}			//拷貝構(gòu)造函數(shù)
    Object &operator=() {const Object &obj} //賦值函數(shù)
    {
        return *this;
    }
    
    Object *operator&()						//普通對(duì)象的&(取地址符)的重載
    {
        return this;
    }
    
    const Object *operator&() const			//常對(duì)象的&(取地址符)重載
    {
        return this;
    }

};

然后,在C11標(biāo)準(zhǔn)下,又增添了兩個(gè)缺省函數(shù),這里不做深究:

移動(dòng)構(gòu)造函數(shù)移動(dòng)賦值函數(shù)

3、重載賦值運(yùn)算符解析

回到最初的例子:

class Object
{
    int value;
public:
    Object ()   {
        cout << "create:" << this << endl;
    }                  //普通構(gòu)造函數(shù)
    Object (int x = 0):value(x) {cout << "create:" << this << endl;}  //缺省構(gòu)造函數(shù)
    ~Object()                       //析構(gòu)函數(shù)
    {
        cout << "~Objcet() " << this << endl;
    }
    Object(Object &obj):value(obj.value)             
    {
        cout << "Copy create:" << this << endl;
    }

    int & Value()
    {
        return value;
    }

    const int &Value() const 
    {
        return value;
    }  
       
     Object &operator=(const Object& obj)        //此處加引用
    {
        this->value = obj.value;
        return *this;       //this指針指向objb的地址。賦值函數(shù)結(jié)束后,objb不會(huì)被消亡,所以可以以引用返回
    }
    
	void operator=(const Object& obj)       //賦值語(yǔ)句不可給this指針加const
    {
        this->value = obj.value;
    }
    
};

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

我們?cè)?4行添加一個(gè)等號(hào)運(yùn)算符重載函數(shù): void operator=(const Object& obj)

此處不可添加const修飾this指針,因?yàn)樾枰褂胻his指針作為左值被修改。

問題6:void operator=(const Object& obj) 只能用于 obja = objb,為什么不可以這樣使用 obja = objb = objc;

我們逐一分析:

obja = objb = objc;

//當(dāng)調(diào)用等號(hào)運(yùn)算符函數(shù)的時(shí)候。
obja = objb.operator = (objc);
obja = operator = (&objb,objc);
//如果此處是調(diào)用的是 void operator=(const Object& obj) ;
//等號(hào)從右向左指向,我們不能把一個(gè)void 類型賦給一個(gè)obja對(duì)象類型。

我們將賦值運(yùn)算符進(jìn)行再次重載,丟棄 void 版本:

Object &operator=(const Object& obj)        //此處加引用
{
	this->value = obj.value;
	return *this;       //this指針指向objb的地址。賦值函數(shù)結(jié)束后,objb不會(huì)被消亡,所以可以以引用返回
}

這樣就可以使用了。

我們接著上次的深入分析:

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

問題7:如果遇到obja = obja這種情況,如何賦值呢?

回答:對(duì)this指針和形參引用進(jìn)行判斷。

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

問題8:為什么函數(shù)是在棧區(qū)構(gòu)建的,以引用返回打印的不是一個(gè)隨機(jī)值?

運(yùn)行程序,VS2012中,打印的是一個(gè)隨機(jī)值。

VS2019打印的是一個(gè)正常值。

c));

> 問題7:如果遇到obja = obja這種情況,如何賦值呢?
>
> 回答:對(duì)this指針和形參引用進(jìn)行判斷。

```cpp
Object &operator=(const Object &obj)
{
    if(this != &obj)
    {
        this->value = obj.value
    }
}

問題8:為什么函數(shù)是在棧區(qū)構(gòu)建的,以引用返回打印的不是一個(gè)隨機(jī)值?

運(yùn)行程序,VS2012中,打印的是一個(gè)隨機(jī)值。

VS2019打印的是一個(gè)正常值。

在WIN10系統(tǒng)中,VS2019與操作系統(tǒng)完全結(jié)合,安全性更高。當(dāng)程序多次運(yùn)行的時(shí)候,它的邏輯地址都不一樣,這樣做的好處是:當(dāng)病毒入侵時(shí),由于程序的邏輯地址是變化的,病毒不好尋找入侵的入口。

總結(jié)

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

相關(guān)文章

  • C語(yǔ)言順序表的實(shí)現(xiàn)代碼

    C語(yǔ)言順序表的實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)順序表的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • C語(yǔ)言實(shí)現(xiàn)猜拳游戲

    C語(yǔ)言實(shí)現(xiàn)猜拳游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)猜拳游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • c++ dynamic_cast與static_cast使用方法示例

    c++ dynamic_cast與static_cast使用方法示例

    本文用示例講解了dynamic_cast、static_cast子類與基類之間轉(zhuǎn)換功能的使用方法
    2013-11-11
  • VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問題 附源碼

    VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)dll的問題 附源碼

    這篇文章主要介紹了VisualStudio2019構(gòu)建C/C++靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)(dll)(文末附源碼),本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • C語(yǔ)言構(gòu)建連連看游戲(矩陣方式)

    C語(yǔ)言構(gòu)建連連看游戲(矩陣方式)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言構(gòu)建連連看游戲,采用矩陣方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++數(shù)據(jù)結(jié)構(gòu)二叉搜索樹的實(shí)現(xiàn)應(yīng)用與分析

    C++數(shù)據(jù)結(jié)構(gòu)二叉搜索樹的實(shí)現(xiàn)應(yīng)用與分析

    從這篇博客開始,我就要和大家介紹有關(guān)二叉搜索樹的知識(shí),它還衍生出了兩棵樹——AVL樹和紅黑樹,在后面兩篇博客我都會(huì)介紹。今天先從二叉搜索樹開始引入
    2022-02-02
  • va_list(),va_start(),va_arg(),va_end() 詳細(xì)解析

    va_list(),va_start(),va_arg(),va_end() 詳細(xì)解析

    這些宏定義在stdarg.h中,所以用到可變參數(shù)的程序應(yīng)該包含這個(gè)頭文件.下面我們寫一個(gè)簡(jiǎn)單的可變參數(shù)的函數(shù),該函數(shù)至少有一個(gè)整數(shù)參數(shù),第二個(gè)參數(shù)也是整數(shù),是可選的.函數(shù)只是打印這兩個(gè)參數(shù)的值
    2013-09-09
  • C語(yǔ)言實(shí)現(xiàn)文件讀寫操作的幾種常用方法

    C語(yǔ)言實(shí)現(xiàn)文件讀寫操作的幾種常用方法

    C語(yǔ)言提供了一系列文件操作函數(shù),使得我們可以通過程序?qū)ξ募M(jìn)行讀寫操作,本文主要介紹了C語(yǔ)言實(shí)現(xiàn)文件讀寫操作的幾種常用方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • C++?哈希表的基本用法及說明

    C++?哈希表的基本用法及說明

    這篇文章主要介紹了C++?哈希表的基本用法及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 深入學(xué)習(xí)C++智能指針之shared_ptr與右值引用的方法

    深入學(xué)習(xí)C++智能指針之shared_ptr與右值引用的方法

    智能指針的核心實(shí)現(xiàn)技術(shù)是引用計(jì)數(shù),每使用它一次,內(nèi)部引用計(jì)數(shù)加1,每析構(gòu)一次內(nèi)部的引用計(jì)數(shù)減1,減為0時(shí),刪除所指向的堆內(nèi)存,今天通過本文給大家分享C++智能指針之shared_ptr與右值引用的方法,需要的朋友跟隨小編一起看看吧
    2021-07-07

最新評(píng)論