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

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

 更新時間:2021年04月06日 09:30:17   作者:txf620  
這篇文章主要介紹了C++ 運(yùn)算符重載中返回值的坑,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

相信不少朋友在學(xué)習(xí)運(yùn)算符重載的時候,都會被參數(shù)與返回值應(yīng)該是左值引用,還是右值引用,還是const常量所困擾。當(dāng)然我無法一一枚舉,這次先講一下返回值的坑 (沒錯就是我親手寫的bug)

E0334 “Myclass” 沒有適當(dāng)?shù)膹?fù)制構(gòu)造函數(shù)

其實(shí)這個問題的根源是,沒有定義常量參數(shù)類型的拷貝構(gòu)造函數(shù)所致
先來看看代碼

//頭文件head.h
class Myclass
{
private:
 int a;
public:
 Myclass(int b=0):a(b) {} //構(gòu)造函數(shù)
 Myclass(Myclass& c);  //復(fù)制構(gòu)造函數(shù)
 ~Myclass(){}   //析構(gòu)函數(shù)
 Myclass operator+(Myclass& d); //重載+運(yùn)算符
 friend ostream& operator<<(ostream& os ,const Myclass& d);
     //重載<<運(yùn)算符
};
//以下是定義
Myclass::Myclass(Myclass& c)
{
 a = c.a;
}
Myclass Myclass::operator+(Myclass& d)
{
 return Myclass(d.a+a);  //!!此處報(bào)錯
}
ostream& operator<<(ostream& os,const Myclass& d)
{
 os << d.a << std::endl;
 return os;
}
//main.cpp
#include"head.h"
int main()
{
 Myclass a1(5);
 Myclass a2(12);
 Myclass sum = a1 + a2; //?。〈颂巿?bào)錯
 std::cout << sum;
}

代碼在VS中,又出現(xiàn)了令人討厭的小紅線,沒有適當(dāng)?shù)膹?fù)制構(gòu)造函數(shù),這就有疑問了, 不是明明有個構(gòu)造函數(shù)Myclass(int b=0):a(b) {}嗎,參數(shù)是int很合適??? 于是,我們定義一個臨時變量temp,再將它返回,此時會隱式調(diào)用拷貝構(gòu)造函數(shù)而后返回一個副本后原來的temp就die了,因此返回值不可以是引用。下面是代碼

Myclass Myclass::operator+(Myclass& d)
{
 Myclass temp(d.a + a);
 return temp;
}

此時第一處報(bào)錯消失了,但是第二處報(bào)錯依然存在,而且仍為 “沒有適當(dāng)?shù)膹?fù)制構(gòu)造函數(shù)”,這就說明了,我的入手方向應(yīng)該是拷貝構(gòu)造函數(shù)

經(jīng)過博主的調(diào)試,得知是因?yàn)楹瘮?shù)的返回值是一個純右值,為了驗(yàn)證這個想法,使用了右值引用,來接收這個純右值(當(dāng)然,右值引用更多的是用在移動構(gòu)造函數(shù)上,將 將亡值“偷”出來)

#include"head.h"
int main()
{
 Myclass a1(5);
 Myclass a2(12);
 Myclass&& sum = a1 + a2;
}
 

果然,它不報(bào)錯了

但是考慮到實(shí)用性,總不能讓用戶今后做個加法都要用右值引用接收吧,因此,我們要從源頭解決,即重載拷貝構(gòu)造函數(shù)。

值得思考的是,右值不就是被賦值的那個嗎,為什么用Myclass&& sum = a1 + a2;無法賦值呢?眾所周知,Myclass&& sum = a1 + a2;調(diào)用的是拷貝構(gòu)造函數(shù),類不同于基本數(shù)據(jù)類型,它要通過程序員來設(shè)置一系列的功能,我們沒有設(shè)置接受,Myclass類型的右值的功能,只定義了接受int類型的右值的功能,這自然是不行的了。
因此,重載拷貝構(gòu)造函數(shù)

Myclass::Myclass(const Myclass& c)
{
 a = c.a;
}

此時就能運(yùn)行了

E0349 沒有與這些操作數(shù)匹配的 “<<” 運(yùn)算符

關(guān)于流運(yùn)算符為什么要寫成$ostream& operator<<(ostream& os,const Myclass& d); 而非ostream& operator<<(ostream& os,Myclass& d);這個問題,網(wǎng)上絕大部分的回答都是輸出沒必要修改值。那么我們先定義后者

#head.h
#pragma once
#include<iostream>
using std::ostream;
class Myclass
{
private:
 int a;
public:
 Myclass(int b=0):a(b) {}
 Myclass(Myclass& c);
 Myclass(const Myclass& c);
 ~Myclass(){}
 Myclass operator+(Myclass& d);
 friend ostream& operator<<(ostream& os ,Myclass& d);
};
Myclass::Myclass(const Myclass& c)
{
 a = c.a;
}
Myclass::Myclass(Myclass& c)
{
 a = c.a;
}
Myclass Myclass::operator+(Myclass& d)
{
 Myclass temp(d.a + a);
 return temp;
}
ostream& operator<<(ostream& os,Myclass& d)
{
 os << d.a << std::endl;
 return os;
}
#main.cpp
#include"head.h"
int main()
{
 Myclass a1(5);
 Myclass a2(12);
 Myclass&& sum = a1 + a2; 
 std::cout << a1 + a2;  //此處有討厭小紅線
}
 

不難發(fā)現(xiàn),討厭的小紅線又出來了。
我們可以想象一下這個過程,a1.operator+(a2),返回了個臨時變量,暫且假設(shè)它叫newguy,那么newguy為一個右值,又調(diào)用了函數(shù)os.<<(&d),傳參為&d=newguy,現(xiàn)在問題來了,左值引用怎么能夠接受一個純右值呢? 而我們定義的重載的流運(yùn)算符接受的參數(shù)類型為左值,我們并沒有給出從左值到右值強(qiáng)制類型轉(zhuǎn)換的函數(shù),但是在上一部分,我們給出了從右值到左值的拷貝構(gòu)造函數(shù),因此,將流運(yùn)算符聲明為前者更好。

C3861 “function”: 找不到標(biāo)識符

這個問題應(yīng)該是非常常見的,不習(xí)慣將函數(shù)(或是類)先聲明后定義而又喜歡讓函數(shù)(或是類)相互調(diào)用,但是在類模板它比以上兩種更為隱蔽。

#include<iostream>
class A
{
 friend void show();  //“聲明”函數(shù)
 friend void show1(); //“聲明”函數(shù)
}; 
void show()   //定義
{
 show1();
}
void show1(){}   //定義
int main()
{
 A a;
 show();   //調(diào)用
 show1();   //調(diào)用
}

以上流程看似聲明->定義->調(diào)用非常完美,實(shí)則還是會報(bào)錯的,不過跟以上兩種不一樣的是,它是在linking的時候出錯,這是為什么呢?

原來友元函數(shù)并不屬于這個類的一部分,在類內(nèi)定義僅僅是為了告訴編譯器“這個函數(shù)是這個類的友元函數(shù)”,并沒有對這個函數(shù)本身進(jìn)行聲明,因此,正確的做法應(yīng)該是這樣的:

#include<iostream>
void show();
void show1();
class A
{
 friend void show();
 friend void show1();
}; 
void show()
{
 show1();
}
void show1(){}
int main()
{
 A a;
 show();
 show1();
}

總結(jié)

本文主要講了三點(diǎn)。
首先,要注意將拷貝構(gòu)造函數(shù)重載。
其次,要將流運(yùn)算符<<的參數(shù)類型確定為(ostream&,const myclass&),當(dāng)然,istream則萬萬不可const,ostream是沒有拷貝構(gòu)造函數(shù)的,因此引用也是必須的。
最后,類內(nèi)友元函數(shù)的聲明,并不等同于函數(shù)本身的聲明。

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

相關(guān)文章

  • C++:構(gòu)造函數(shù),析構(gòu)函數(shù)詳解

    C++:構(gòu)造函數(shù),析構(gòu)函數(shù)詳解

    今天小編就為大家分享一篇關(guān)于C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的文章,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2021-09-09
  • C++之文件輸入/輸出流類解讀

    C++之文件輸入/輸出流類解讀

    這篇文章主要介紹了C++之文件輸入/輸出流類,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C++ 如何使用RapidJson 寫入文件

    C++ 如何使用RapidJson 寫入文件

    RapidJSON 是只有頭文件的 C++ 庫, 不需要編譯, 可以直接在項(xiàng)目中使用, 只需把 include/rapidjson 目錄復(fù)制至系統(tǒng)或項(xiàng)目的 include 目錄即可,下面給大家分享C++ 如何使用RapidJson 寫入文件,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • C++中關(guān)于多態(tài)實(shí)現(xiàn)和使用方法

    C++中關(guān)于多態(tài)實(shí)現(xiàn)和使用方法

    這篇文章主要介紹了C++中關(guān)于多態(tài)實(shí)現(xiàn)和使用方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++如何獲取鼠標(biāo)點(diǎn)擊位置

    C++如何獲取鼠標(biāo)點(diǎn)擊位置

    這篇文章主要介紹了C++如何獲取鼠標(biāo)點(diǎn)擊位置問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C++命名空間使用詳細(xì)介紹

    C++命名空間使用詳細(xì)介紹

    考慮一種情況,當(dāng)我們有兩個同名的人,Zara,在同一個班里。當(dāng)我們需要對它們進(jìn)行區(qū)分我們必須使用一些額外的信息和它們的名字,比如它們生活在不同的區(qū)域或者興趣愛好什么的,在C++程序中也會遇到同樣的情況,所以命名空間就此產(chǎn)生
    2022-09-09
  • C++中string的模擬實(shí)現(xiàn)

    C++中string的模擬實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了C++中string的模擬實(shí)現(xiàn),感興趣的小伙伴們可以參考一下
    2016-08-08
  • vscode?采用C++17版本進(jìn)行編譯的實(shí)現(xiàn)

    vscode?采用C++17版本進(jìn)行編譯的實(shí)現(xiàn)

    本文主要介紹了vscode?采用C++17版本進(jìn)行編譯,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C/C++編寫推箱子小游戲

    C/C++編寫推箱子小游戲

    這篇文章主要為大家詳細(xì)介紹了C/C++編寫推箱子小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語言實(shí)現(xiàn)數(shù)組轉(zhuǎn)置的代碼詳解

    C語言實(shí)現(xiàn)數(shù)組轉(zhuǎn)置的代碼詳解

    在現(xiàn)代計(jì)算中,數(shù)組是最基礎(chǔ)且最常用的數(shù)據(jù)結(jié)構(gòu)之一,無論是對圖像像素進(jìn)行旋轉(zhuǎn),還是對大規(guī)模數(shù)值數(shù)據(jù)做格式轉(zhuǎn)換,都離不開“轉(zhuǎn)置(Transpose)”操作,所以本文將詳細(xì)介紹C語言實(shí)現(xiàn)數(shù)組轉(zhuǎn)置的方法,需要的朋友可以參考下
    2025-05-05

最新評論