網站首頁 編程語言 正文
重載運算符時是作為成員函數還是非成員函數?
對于很多運算符來說,可以選擇使用成員函數或者非成員函數來實現運算符重載,一般來說,非成員函數應該是友元函數,這樣才能夠使非成員函數可以訪問類的私有數據。
非成員版本的重載運算符所需要的形參數目與運算符使用的操作數數目相同,而成員版本所需要的參數數目少一個,因為其中一個操作數是被隱式傳遞的。
假如要重載加法運算符,可以有下面兩種形式:
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
相關推薦
- 2022-10-29 node-sass安裝失敗解決方法
- 2022-03-30 python怎么使用xlwt操作excel你知道嗎_python
- 2022-02-27 springboot引入依賴lombok但是@Data(lombok的一個注解)仍然爆紅
- 2022-10-25 基于Linux服務器出現“No space left on device”錯誤的解決簡單有效方案
- 2023-04-06 C語言中單鏈表的基本操作(創建、銷毀、增刪查改等)_C 語言
- 2022-05-17 SQL?Server實現分頁方法介紹_MsSql
- 2022-04-09 C#8.0中的索引與范圍功能介紹_C#教程
- 2023-11-24 局部路由守衛component守衛
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支