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

C++類中的運(yùn)算符重載過(guò)程

 更新時(shí)間:2024年11月13日 11:32:13   作者:gemluoye  
文章介紹了運(yùn)算符重載在C++中的重要性以及實(shí)現(xiàn)方法,包括加法運(yùn)算符重載、左移運(yùn)算符重載、遞增運(yùn)算符重載、+=運(yùn)算符重載、關(guān)系運(yùn)算符重載和賦值運(yùn)算符重載

為什么要實(shí)現(xiàn)運(yùn)算符重載?

在 C++ 中,運(yùn)算符最初是為內(nèi)置類型(如intdouble等)定義操作方式。當(dāng)定義一個(gè)新的類(自定義類型)時(shí),編譯器并不清楚如何對(duì)這個(gè)新類型的成員變量應(yīng)用運(yùn)算符。

通過(guò)運(yùn)算符重載,程序員可以明確地告訴編譯器對(duì)于該類的對(duì)象,運(yùn)算符(如+、-*等)應(yīng)該如何操作其成員變量,從而使自定義類型能夠像內(nèi)置類型一樣自然地使用這些運(yùn)算符。

1.加法運(yùn)算符重載

作用:實(shí)現(xiàn)兩個(gè)自定義類型數(shù)據(jù)的加法運(yùn)算

在類內(nèi)實(shí)現(xiàn)加法運(yùn)算符重載

#include <iostream>
using namespace std;
class Person {
    int age;
    int money;

public:
    Person() : money(0), age(0) {}
    Person(int val, int val2) : age(val), money(val2) {}
    Person(const Person& other) {
        this->age = other.age;
        this->money = other.money;
    }
    // 類內(nèi)實(shí)現(xiàn)+重載 本質(zhì):Person p3=p1.operator+(p2)
    Person operator+(const Person& other) {
        Person p;
        p.age = this->age + other.age;
        p.money = this->money + other.money;
        return p; // 不以引用返回是因?yàn)椋趫?zhí)行完這個(gè)函數(shù)后,p會(huì)被銷毀,以值傳遞會(huì)調(diào)用拷貝構(gòu)造
    }
    void print() { cout << age << " " << money << endl; }
};

int main() {
    Person a(18, 50);    // 括號(hào)法
    Person b = {12, 50}; // 隱式轉(zhuǎn)換法
    Person c = a + b;
    c.print();
    return 0;
}

實(shí)現(xiàn)加法運(yùn)算符重載的operator+函數(shù)來(lái)完成的,傳入的參數(shù)為const Person& other的原因有以下的兩點(diǎn):

  • 1.以引用的方式傳遞是為了防止調(diào)用拷貝構(gòu)造
  • 2.加const修飾是為了防止修改實(shí)參

在函數(shù)中聲明了一個(gè)Person的對(duì)象p,返回值是以值的形式返回,因?yàn)橹捣祷貢?huì)調(diào)用拷貝構(gòu)造,如果是以引用的方式傳遞,當(dāng)這個(gè)函數(shù)結(jié)束時(shí),對(duì)象p就會(huì)被銷毀掉。

在類外實(shí)現(xiàn)加法運(yùn)算符重載

#include <iostream>
using namespace std;
class Person {
    int age;
    int money;
    friend Person operator+(const Person& other1, const Person& other2);

public:
    Person() : money(0), age(0) {}
    Person(int val, int val2) : age(val), money(val2) {}
    Person(const Person& other) {
        this->age = other.age;
        this->money = other.money;
    }
    void print() { cout << age << " " << money << endl; }
};
// 類外實(shí)現(xiàn)+重載 本質(zhì):Person p3=operator+(p1,p2)
Person operator+(const Person& other1, const Person& other2) {
    Person p;
    p.age = other1.age + other2.age;
    p.money = other1.money + other2.money;
    return p;
}
int main() {
    Person a(18, 50);    // 括號(hào)法
    Person b = {12, 50}; // 隱式轉(zhuǎn)換法
    Person c = a + b;
    c.print();
    return 0;
}

在類外實(shí)現(xiàn)加法運(yùn)算符重載,相當(dāng)于類外函數(shù)訪問(wèn)類內(nèi)的成員變量,所以要將這個(gè)函數(shù)在類中聲明為友元函數(shù)(friend)。其他的跟在類內(nèi)實(shí)現(xiàn)加法運(yùn)算符重載是一樣的。

本質(zhì):在類內(nèi)實(shí)現(xiàn)加法運(yùn)算符重載的本質(zhì)是:Person p3=p1.operator(p2)

在類外實(shí)現(xiàn)加法運(yùn)算符重載的本質(zhì)是:Person p3=operator+(p1,p2)

因?yàn)橐粋€(gè)是通過(guò)對(duì)象去調(diào)用這個(gè)函數(shù),它本身也算是一個(gè)參數(shù),所以只需要傳人一個(gè)參數(shù)。而在類外,則是相當(dāng)于直接調(diào)用這個(gè)函數(shù),所以傳入的參數(shù)是兩個(gè)。

無(wú)論是再類內(nèi)還是在類外實(shí)現(xiàn)加法運(yùn)算符重載,最后調(diào)用的方式都是+。

2.左移運(yùn)算符重載

作用:可以輸出自定義數(shù)據(jù)類型

要在類外實(shí)現(xiàn),因?yàn)樵陬悆?nèi)的話,調(diào)用格式為:對(duì)象.operator();無(wú)法達(dá)到cout<<

#include <iostream>
using namespace std;
class Person {
    int age;
    int money;

public:
    friend ostream& operator<<(ostream& o, const Person& p);
    Person() : age(0), money(0) {}
    Person(int val, int val2) : age(val), money(val2) {}
    Person(const Person& other) {
        cout << "調(diào)用拷貝構(gòu)造";
        this->age = other.age;
        this->money = other.money;
    }
    // 一般不在函數(shù)內(nèi)進(jìn)行左移重載
    /*void operator<<(ostream& cout,const Person p) {

    }*/
};
// 類外實(shí)現(xiàn)左移運(yùn)算符重載
ostream& operator<<(ostream& o, const Person& p) {
    o << p.age << " " << p.money << endl;
    return o;
}
int main() {
    Person a(5, 12), b;
    cout << a << b << endl;
    return 0;
}

因?yàn)槭窃陬愅鈱?shí)現(xiàn)的,所以在類內(nèi)要將其設(shè)置為友元函數(shù)。參數(shù)為兩個(gè),一個(gè)為ostream類型的o,另外一個(gè)為引用類型的對(duì)象。

返回值為引用類型的ostream類型的ostream,因?yàn)槿绻胍M(jìn)行連續(xù)的輸出,就必須讓前一個(gè)的結(jié)果作為第二個(gè)左移運(yùn)算符的第一個(gè)參數(shù),如下圖:

在o<<p.age的返回值為o,然后它與后面就變成了o<<" ",接著又調(diào)用這個(gè)運(yùn)算符,這樣才能完成連續(xù)的輸出。

3.遞增運(yùn)算符重載

遞增分為兩種一種是前++,一種是后++。前++是在使用之前就讓這個(gè)數(shù)加1,返回的是加1之后的結(jié)果。而后++是先返回這個(gè)數(shù)再進(jìn)行加一操作。

前++返回的是引用,后++返回的是值。

#include <iostream>
using namespace std;
class Person {
    int age;
    int money;

public:
    Person() : age(0), money(0) {}
    Person(int val, int val2) : age(val), money(val2) {}
    Person(const Person& other) {
        this->age = other.age;
        this->money = other.money;
    }
    // 前置++的重載  返回引用
    Person& operator++() { // 保證是對(duì)一個(gè)數(shù)進(jìn)行++
        this->age++;
        this->money++;
        return *this;
    }
    // 后置++的重載 加一個(gè)int參數(shù)占位符區(qū)分 返回值
    Person operator++(int) {
        Person temp = *this; // 用一個(gè)局部變量返回++之前的結(jié)果
        this->age++;
        this->money++;
        return temp;
    }
    void print() { cout << age << " " << money; }
};
int main() {
    Person p(5, 12);
    ++p;
    p.print();
    return 0;
}

對(duì)前++和后++都是operator++,所以為了區(qū)分,對(duì)于后++來(lái)說(shuō),需要加一個(gè)參數(shù)占位符來(lái)進(jìn)行區(qū)分。

在返回值這塊,前++返回的是引用,因?yàn)橐氖撬M(jìn)行加一之后的結(jié)果,所以可以直接返回這個(gè)對(duì)象。

而后++則返回的是一個(gè)值,因?yàn)橐祷氐氖撬右恢暗慕Y(jié)果,所以需要一個(gè)局部變量返回++之前的結(jié)果。

4.+=運(yùn)算符重載

#include <iostream>
using namespace std;
class Person {
    int age;
    int money;

public:
    friend ostream& operator<<(ostream& o, const Person& p);
    Person() : age(0), money(0) {}
    Person(int val, int val2) : age(val), money(val2) {}
    Person(const Person& other) {
        this->age = other.age;
        this->money = other.money;
    }
    Person& operator+=(const Person& other) {
        this->age += other.age;
        this->money += other.money;
        return *this;
    }
    void print() { cout << age << " " << money; }
};
ostream& operator<<(ostream& o, const Person& p) {
    o << p.age << " " << p.money << endl;
    return o;
}
int main() {
    Person a(1, 1), b(2, 2), c(3, 3);
    a += b += c;
    cout << a << b << c;
    return 0;
}

+=運(yùn)算符的返回值也是對(duì)象本身,因?yàn)闀?huì)涉及到連續(xù)+=的情況,和左移運(yùn)算符的重載類似。

這樣才能實(shí)現(xiàn)連續(xù)+=的實(shí)現(xiàn)。如上面代碼運(yùn)行的結(jié)果為:

要注意運(yùn)算的順序是從右往左進(jìn)行計(jì)算的。

5.關(guān)系運(yùn)算符和賦值運(yùn)算符重載

#include <iostream>
using namespace std;
class A {
    int num;
    int* p;

public:
    A() : num(0), p(nullptr) {}
    A(int x) : num(x), p(new int(num)) {}
    A(const A& other) { this->num = other.num; }
    bool operator>(const A& other) {
        if (this->num > other.num)
            return 1;
        else
            return 0;
    }
    bool operator==(const A& other) {
        if (this->num == other.num)
            return 1;
        else
            return 0;
    }
    A& operator=(const A& other) {
        if (p)
            delete p; // 釋放原來(lái)的堆區(qū)內(nèi)存,拷貝構(gòu)造沒(méi)有這一步
        num = other.num;
        p = new int(num); // 指向新的堆區(qū)內(nèi)存
        return *this;
    }
};
int& fun() {
    int a = 2;
    return a;
}
int main() {
    int x = fun();  // 行
    int& y = fun(); // 不行
    A a(2), b(3), c;
    cout << (a == b);
    a = b =c; // 如果類內(nèi)沒(méi)有實(shí)現(xiàn)賦值運(yùn)算符,編譯器則會(huì)提供默認(rèn)的賦值運(yùn)算符,每個(gè)成員變量都會(huì)被賦值,此時(shí)要注意淺拷貝問(wèn)題
    return 0;
}

關(guān)系運(yùn)算符主要包括==、>、<等,他們的返回值都是bool類型。

賦值運(yùn)算符,就是把other的值給調(diào)用它的對(duì)象,如果不對(duì)賦值運(yùn)算符進(jìn)行重載的話,那么它就會(huì)是簡(jiǎn)單的賦值操作,這里就會(huì)導(dǎo)致淺拷貝的問(wèn)題(可以看作者前面提到的淺拷貝和深拷貝問(wèn)題)。所以我們就需要對(duì)它進(jìn)行重載。

在上述代碼中,因?yàn)閜是一塊指向堆區(qū)的指針變量,所以在進(jìn)行賦值運(yùn)算符重載時(shí),需要開(kāi)辟一塊新的堆區(qū),然后保證兩個(gè)堆區(qū)的內(nèi)容一樣。同時(shí),還有保證之前這個(gè)指針變量p有沒(méi)有指向別的堆區(qū)內(nèi)容,如果有,就將它釋放,避免內(nèi)存泄漏。返回值為引用類型,返回對(duì)象本身。

注意:賦值運(yùn)算符也是編譯器給一個(gè)類至少添加的函數(shù)。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)順序表的插入刪除

    C語(yǔ)言實(shí)現(xiàn)順序表的插入刪除

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)順序表的插入刪除,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 輸入一個(gè)字符串,取出其中的整數(shù)(實(shí)現(xiàn)代碼)

    輸入一個(gè)字符串,取出其中的整數(shù)(實(shí)現(xiàn)代碼)

    輸入一個(gè)字符串,內(nèi)含所有數(shù)字和非數(shù)字字符。將其中連續(xù)的數(shù)字作為一個(gè)整數(shù),依次存放到一個(gè)數(shù)組中,統(tǒng)計(jì)共有多少個(gè)整數(shù),并輸出這些數(shù)
    2013-09-09
  • C語(yǔ)言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)

    C語(yǔ)言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)

    fgetc() 和 fputc() 函數(shù)每次只能讀寫一個(gè)字符,速度較慢,實(shí)際開(kāi)發(fā)中往往是每次讀寫一個(gè)字符串或者一個(gè)數(shù)據(jù)塊,這樣能明顯提高效率,這篇文章主要給大家介紹了關(guān)于C語(yǔ)言入門學(xué)習(xí)之fgets()函數(shù)和fputs()函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 一文掌握C++ const與constexpr及區(qū)別

    一文掌握C++ const與constexpr及區(qū)別

    C++ 11標(biāo)準(zhǔn)中,const 用于為修飾的變量添加“只讀”屬性而 constexpr關(guān)鍵字則用于指明其后是一個(gè)常量,編譯器在編譯程序時(shí)可以順帶將其結(jié)果計(jì)算出來(lái),而無(wú)需等到程序運(yùn)行階段,這樣的優(yōu)化極大地提高了程序的執(zhí)行效率,本文重點(diǎn)介紹C++ const與constexpr區(qū)別介紹,一起看看吧
    2024-02-02
  • 利用C語(yǔ)言實(shí)現(xiàn)三子棋游戲

    利用C語(yǔ)言實(shí)現(xiàn)三子棋游戲

    這篇文章主要為大家詳細(xì)介紹了利用C語(yǔ)言實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • C++騎士游歷問(wèn)題(馬踏棋盤)解析

    C++騎士游歷問(wèn)題(馬踏棋盤)解析

    這篇文章主要為大家詳細(xì)介紹了C++騎士游歷問(wèn)題的解答思路,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C語(yǔ)言中的函數(shù)指針學(xué)習(xí)筆記

    C語(yǔ)言中的函數(shù)指針學(xué)習(xí)筆記

    這篇文章主要介紹了C語(yǔ)言中的函數(shù)指針的一些學(xué)習(xí)知識(shí)點(diǎn)記錄,文中作者整理了一些比較interesting的函數(shù)指針用法,需要的朋友可以參考下
    2016-04-04
  • 從C++單例模式到線程安全詳解

    從C++單例模式到線程安全詳解

    下面小編就為大家?guī)?lái)一篇從C++單例模式到線程安全詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • C語(yǔ)言結(jié)構(gòu)體計(jì)算內(nèi)存占用問(wèn)題解析

    C語(yǔ)言結(jié)構(gòu)體計(jì)算內(nèi)存占用問(wèn)題解析

    這篇文章主要介紹了C語(yǔ)言結(jié)構(gòu)體計(jì)算內(nèi)存占用問(wèn)題解析,本文通過(guò)案例來(lái)解析了C語(yǔ)言計(jì)算結(jié)構(gòu)體內(nèi)存的方式和方法,需要的朋友可以參考下
    2021-07-07
  • C++類基本語(yǔ)法實(shí)例分析

    C++類基本語(yǔ)法實(shí)例分析

    這篇文章主要介紹了C++類基本語(yǔ)法實(shí)例分析,非常適合初學(xué)者學(xué)習(xí)借鑒,需要的朋友可以參考下
    2014-08-08

最新評(píng)論

常宁市| 三河市| 南投县| 新巴尔虎左旗| 莱阳市| 易门县| 四川省| 万州区| 石狮市| 开化县| 丰城市| 潢川县| 涿鹿县| 射洪县| 林西县| 响水县| 仪征市| 榆中县| 海淀区| 乐昌市| 阿克陶县| 兴文县| 大化| 古交市| 建瓯市| 山东省| 都匀市| 山阴县| 鄂托克前旗| 宁安市| 紫阳县| 洛隆县| 石渠县| 江源县| 吉林市| 黄龙县| 乌兰察布市| 新乡县| 北宁市| 镇远县| 景德镇市|