最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于C++運算符重載的一些困惑詳解

 更新時間:2021年04月23日 09:52:54   作者:bruce628  
這篇文章主要給大家介紹了關(guān)于C++運算符重載的一些困惑,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一.背景

在復(fù)習(xí)《C++基礎(chǔ)與提高》時,自己實現(xiàn)運算符重載(i++)時,幾次都報錯。其實還是自己對運算符重載這一部分內(nèi)容理解得不夠透徹,于是再次看了下書上的內(nèi)容,理解算是加深了一些,于是提筆記錄一下。

環(huán)境:win10,QT4.8

二.概述

這部分內(nèi)容主要關(guān)于在重載函數(shù)中,函數(shù)前要不要加const,何時加const,返回類型要不要加&(引用)修飾,何時加&(引用)的問題,還有臨時對象的問題。關(guān)于為什么要重載,重載的規(guī)則,友元重載、成員重載的區(qū)別之類的知識點,這里就不贅述了。

三.內(nèi)容

以類Complex為例

class Complex
{
public:
    Complex(double x = 0, double y = 0)
        :m_x(x), m_y(y){}

    void dis()
    {
        cout<<"("<<m_x<<", "<<m_y<<")"<<endl;
    }
protected:
    double m_x;
    double m_y;
};

1.以實現(xiàn)單目運算符prefix++和surfix++為例。

先提這個例子,一是因為我在復(fù)習(xí)這塊時遇到了一點問題,二是這個有點特別,涉及到啞元的問題。

prefixe++

1).考慮基本數(shù)據(jù)類型,以int類型為例,如下的操作都是可以的;

int a = 1;
++a;
++++a;

2).先實現(xiàn)基本的語義,代碼如下:

Complex Complex::operator++(void)
{
    m_x++;
    m_y++;
    return *this;
}

3)考慮添加

重載函數(shù)返回的是對象自身,并且需要修改對象,我們即可以想到返回的是引用類型。注意,此時引用指向的對象在重載函數(shù)調(diào)用時就已經(jīng)存在了。

4)先運行一下,看下是否能編譯通過

++c1;

++++c1;

此時重載函數(shù)實現(xiàn)的效果,與基本類型效果一致,符合預(yù)期,此時就不考慮重載函數(shù)前面是否加const修飾了。

#include <iostream>

using namespace std;

class Complex
{
public:
    Complex(double x = 0, double y =0)
        :m_x(x), m_y(y){}

    void dis()
    {
        cout<<"("<<m_x<<", "<<m_y<<")"<<endl;
    }

    Complex & operator++(void);
protected:
    double m_x;
    double m_y;
};

Complex & Complex::operator++(void)
{
    m_x++;
    m_y++;
    return *this;
}

int main()
{
    double a = 1.0;
    cout<<++a<<endl;
    ++++a;
    cout<<a<<endl;

    Complex c1(1.0, 2.0);

    Complex cc = ++c1;
    cc.dis();
    cc = ++++c1;  // cc = (c1.operator++()).operator++();
    cc.dis();


    return 0;
}

結(jié)果如下

surfix++

為了區(qū)分prefix++和surfix++兩個成員函數(shù),須使用啞元進(jìn)行區(qū)分(引入 啞元,增加了入?yún)⒌姆绞剑谡{(diào)用時不需要添加任何的參數(shù)),其實類似一個占位符。

1).考慮基本數(shù)據(jù)類型,以int類型為例,可以進(jìn)行的操作和不可以進(jìn)行的操作

int b = 1;
b++;  // 支持
b++++;  // 不支持

2).先實現(xiàn)基本的語義,代碼如下

Complex operator++(int)
    {
        Complex temp = *this;
        m_x++;
        m_y++;
        return temp;
    }

3)考慮添加

可以觀察到,重載函數(shù)返回的是一個臨時對象。若是串聯(lián)調(diào)用,這個臨時對象它又會調(diào)用一次此重載函數(shù)

c1.operator++(0).operator++(0);

調(diào)用完,然后就消失了。

此時切不可在返回類型中添加&。原因如下:

【不要返回局部對象的引用或指針】

函數(shù)完成后,它所占用的存儲空間也隨之被釋放掉。因此,函數(shù)終止意味著局部變量的引用將指向不再有效的內(nèi)存區(qū)域。同樣地,函數(shù)終止,局部對象被釋放,指針將指向一個不存在的對象。

4)先運行一下,看下是否能編譯通過

我們會發(fā)現(xiàn),第34行無法通過編譯,但是第42行可以通過編譯。

5)重載的運算符是否會導(dǎo)致表達(dá)式可以被賦值,應(yīng)該以基礎(chǔ)類型為準(zhǔn),如int a, b, c; (a=b)=c;是可以的,而(a+b)=c;是不允許的。返回類型通過加const加以限定來實現(xiàn)。

為了使自定義類型與基本數(shù)據(jù)類型一致,我們在返回類型前面加上const。重載函數(shù)中代碼修改為如下

const Complex operator++(int);

修改之后,我們可以看到,第34行和42行均無法通過編譯,符合預(yù)期。

2.雙目運算符+

1)考慮基本類型,以下操作都是支持的

int a1 = 1, a2 = 2, a3 = 3;
int m;
m = a1+a2;
m = a1+(a2+a3);
m = (a1+a2)+a3;

2)先重載=,成員函數(shù)如下

Complex & Complex::operator=(const Complex &another)
{
    this->m_x = another.m_x;
    this->m_y = another.m_y;
    return *this;
}

3)再重載運算符+,如下:

因為并未修改傳入的參數(shù),所以參數(shù)前加了const

Complex Complex::operator+(const Complex &another)
{
    return Complex(this->m_x + another.m_x, this->m_y + another.m_y);
}

4)返回類型是否需要加const呢?

我們再對比下表達(dá)式的賦值情況,第49行,對于基本類型,臨時對象被賦值的情況編譯無法通過,但是第58行,自定義類型卻編譯通過了。此時,為了使其編譯不過,可通過在返回值類型前加const加以限定。

將代碼

Complex Complex::operator+(const Complex &another);

修改為如下:

const Complex Complex::operator+(const Complex &another);

5)此時,發(fā)現(xiàn)第49和58行均無法通過編譯,同時第55行和第57行也編譯不過了。

這個是為啥呢?

再仔細(xì)看剛修改的代碼和第57行代碼。重載函數(shù)返回類型加了const后,返回的就是const對象了。第57行代碼,c1 + c2 + c3; c1 + c2返回的是const對象,而重載函數(shù)是一個非const函數(shù)。此時,即會報錯。

在const修飾類一節(jié)中,有學(xué)習(xí)過:如果const構(gòu)成函數(shù)重載,const對象只能調(diào)用const函數(shù),非const對象優(yōu)先調(diào)用非const函數(shù)。

調(diào)整,在重載函數(shù)后面添加const,如下:

const Complex Complex::operator+(const Complex &another) const;

四.結(jié)尾

學(xué)無止境,繼續(xù)前行,

參考材料

《C++基礎(chǔ)與提高》 王桂林

《C++ Primer》第5版SB、JL、BE

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

相關(guān)文章

  • 淺談C++11中的幾種鎖

    淺談C++11中的幾種鎖

    本文主要介紹了C++11中的幾種鎖,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++中map容器的具體使用

    C++中map容器的具體使用

    本文主要介紹了C++中map容器的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • OpenMP task construct 實現(xiàn)原理及源碼示例解析

    OpenMP task construct 實現(xiàn)原理及源碼示例解析

    這篇文章主要為大家介紹了OpenMP task construct 實現(xiàn)原理及源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • QT設(shè)置widget背景圖片不影響widget內(nèi)其他控件背景的方法

    QT設(shè)置widget背景圖片不影響widget內(nèi)其他控件背景的方法

    這篇文章主要給大家介紹了關(guān)于QT設(shè)置widget背景圖片不影響widget內(nèi)其他控件背景的方法,軟件的界面為了更直觀或美觀,常常需要通過圖片來表達(dá),需要的朋友可以參考下
    2023-06-06
  • 基于Qt編寫的文件傳輸工具

    基于Qt編寫的文件傳輸工具

    這篇文章主要為大家詳細(xì)介紹了如何基于Qt編寫一個文件傳輸工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • C++中如何將數(shù)據(jù)保存為CSV文件

    C++中如何將數(shù)據(jù)保存為CSV文件

    這篇文章主要介紹了C++中如何將數(shù)據(jù)保存為CSV文件,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語言一看就懂的指針與結(jié)構(gòu)體介紹

    C語言一看就懂的指針與結(jié)構(gòu)體介紹

    指針提供了對地址操作的一種方法,因此,使用指針可使得C語言能夠更高效地實現(xiàn)對計算機底層硬件的操作。另外,通過指針可以更便捷地操作數(shù)組。C數(shù)組允許定義可存儲相同類型數(shù)據(jù)項的變量,結(jié)構(gòu)是C編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許您存儲不同類型的數(shù)據(jù)項
    2022-04-04
  • C語言實現(xiàn)父進(jìn)程主動終止子進(jìn)程的方法總結(jié)

    C語言實現(xiàn)父進(jìn)程主動終止子進(jìn)程的方法總結(jié)

    一般的情況,子進(jìn)程自己運行完后,執(zhí)行exit 或者return 后,父進(jìn)程wait.  waitpid收回子進(jìn)程,但子進(jìn)程是一個循環(huán)等待狀態(tài)不主動退出,父進(jìn)程可以采用文中介紹的幾種方法,需要的朋友可以參考下
    2023-10-10
  • C語言遞歸實現(xiàn)歸并排序詳解

    C語言遞歸實現(xiàn)歸并排序詳解

    這篇文章主要為大家詳細(xì)介紹了C語言遞歸實現(xiàn)歸并排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,?希望能夠給你帶來幫助
    2022-03-03
  • Java?C++?算法題解leetcode669修剪二叉搜索樹示例

    Java?C++?算法題解leetcode669修剪二叉搜索樹示例

    這篇文章主要為大家介紹了Java?C++?算法題解leetcode669修剪二叉搜索樹示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09

最新評論

田阳县| 耿马| 新昌县| 成都市| 朝阳县| 博客| 金山区| 宁国市| 罗源县| 阆中市| 资兴市| 苍南县| 西城区| 神木县| 岑巩县| 祁阳县| 莱阳市| 达州市| 莆田市| 子长县| 洛隆县| 柏乡县| 婺源县| 伊金霍洛旗| 鸡西市| 罗甸县| 腾冲县| 民乐县| 昔阳县| 胶南市| 武宣县| 德格县| 德钦县| 天峨县| 昭觉县| 双桥区| 密云县| 乌兰浩特市| 彰化市| 老河口市| 随州市|