日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++重載運算符時函數類型的選擇與類的類型轉換

作者:_南明_離火_ 更新時間: 2022-07-12 編程語言

重載運算符時是作為成員函數還是非成員函數?

對于很多運算符來說,可以選擇使用成員函數或者非成員函數來實現運算符重載,一般來說,非成員函數應該是友元函數,這樣才能夠使非成員函數可以訪問類的私有數據。

非成員版本的重載運算符所需要的形參數目與運算符使用的操作數數目相同,而成員版本所需要的參數數目少一個,因為其中一個操作數是被隱式傳遞的。

假如要重載加法運算符,可以有下面兩種形式:

stock operator+(const stock& s1)const;//作為成員函數
friend stock operator+(const stock& s1,const stock& s2);//友元函數

但是在定義時必須選擇其中的一種形式,否則會引發沖突,導致編譯錯誤。

正如前面所說的,一些運算符只有成員函數是唯一合法的選擇

請看這里的重載限制

但是有一些則使用非成員函數更好,比如說重載<< 運算符。

對于定義重載運算符函數時的一些小方法

  • 如果方法通過計算得到一個新的類對象,可以考慮是否能夠使用類構造函數來完成這個任務,這樣做可以避免麻煩并且確保對象按照正確的方式創建。

比如說使用成員函數重載加法運算符:

stock stock::operator+(const stock& s)const
{
    return stock(value1+s.value1,value2+s.value2);
}
  • 可以使用友元函數來解決一些交換律問題。

比如說重載乘法運算符時:

stock operator*(const double a)const
{
    return stock(value1*a,value2*a);
}
friend stock operator*(double a,const stock& s)
{
    return s*a;
}
  • 運算符重載通過函數實現,所以只要運算符函數的特征標不同,使用運算符數量與相應的內置C++運算符相同,就可以多次重載同一個目標。

比如說重載 - 運算符

stock operator-(const stock&a)const
{
    return stock(value1-a.value1,value2-a.value2);
}
stock operator-()const
{
    return stock(-value1,-value2);
}

類型轉換

接受一個參數的構造函數為將類型與該參數相同的值轉換為類提供了藍圖,我們可以使用下面的構造函數將double類型值轉換為類對象:

stock(double a);

也就是可以這樣編寫:

stock s1=1.414;

程序使用構造函數創建一個臨時對象,然后通過逐成員賦值的方法將臨時對象的值給所創建的對象,然后刪除臨時對象。

只有接受一個參數的構造函數才能夠作為轉換函數,但是如果第一個參數后的其他參數有默認參數,那么就可以定義具有多個參數的構造函數實現轉換函數:

stock(double a,int b=0);
stock s2=2.732;

將構造函數用于自動類型轉換似乎是一種不錯的特性,但是這卻可能導致意想不到的類型轉換,C++新增了關鍵字explicit (顯式的)可以用于關閉這種功能,只要在聲明構造函數時在前面加上這個關鍵字聲明即可。

explicit stock(double a);

這將關閉隱式轉換,但是仍然允許使用顯示轉換,可以顯示強制轉換:

double a=456.123;
stock s1=(stock)a;
stock s2=stock(a);

編譯器在什么時候才能夠使用類型轉換函數呢?在使用上面的關鍵字后,只能夠顯示強制轉換,沒有用的情況下(以上面的構造函數為例):

  • 將對象初始化為double類型值
  • 將double類型值賦值給對象
  • double類型值傳遞給接受對象參數的函數時
  • 返回值為對象的函數返回double類型值時
  • 在上面任意情況下,使用可轉換為double類型的內置類型時

對于最后一點,函數原型化提供的參數匹配過程,允許使用構造函數來轉換其他數值類型:

int a=666;
stock s1=a;

比如說上面這個,先將int類型轉換為double類型,然后再使用構造函數。

不過要謹記,轉換不能夠存在二義性,假如還定義了:

stock(long a);

這樣的構造函數,那么再有上面的int類型轉換就會引發錯誤,因為int可以轉換為long也可以轉化為double。

轉換函數

上面的類型轉換可以把值轉化為對象,那么可以把對象轉換為值嗎?

這就需要使用特殊的運算符函數——轉換函數

轉換函數是用戶自定義的強制轉換類型,可以像使用強制轉換類型那樣使用它們。

可以顯示的使用也可以讓編譯器決定。

編譯器將查找匹配的轉換函數,如果沒有將給出錯誤信息。

對于轉換函數轉換為typeName 的聲明

operator typeName();

需要注意下面幾點:

  • 轉換函數必須是類方法
  • 轉換函數不能夠指定返回類型
  • 轉換函數不能夠有參數

比如說下面的轉換函數原型和定義:

//轉換函數
operator int() const;
operator double() const;
//函數定義
stock::operator int() const
{
    return int(value1);
}
stock::operator double() const
{
    return double(value2+0.2);
}

另外需要注意,當讓編譯器自己選擇轉換函數時,不要存在有兩義性的用法,否則將會報錯。

比如說:

stock s1(1.4,5.6);
cout<<s1;

第二個語句將會報錯,因為編譯器不知道調用int和double哪一個函數。

在原則上說: 最好使用顯示轉換避免隱式轉換。

在C++98中關鍵字explicit 還不能夠用于轉換函數,在C++11消除了這種限制,可以使用這個關鍵字限定轉換函數以增加安全性。

也可以采用使用非轉換函數替換轉換函數的方法達到相同效果:

int stock::conver_to_int()
{
    return int(value1);
}

用上面這個函數代替轉換函數,這樣,在使用轉換時就必須顯示的使用函數方法,而不會隱式的調用。

原文鏈接:https://blog.csdn.net/weixin_67340472/article/details/125717089

欄目分類
最近更新