若所有的参数皆需要类型转换——请为此采用non-member函数
若所有的參數(shù)皆需要類型轉(zhuǎn)換——請(qǐng)為此采用non-member函數(shù)
經(jīng)常使用C++的程序猿(希望更多的程序媛),一般不會(huì)同意讓classes支持類型轉(zhuǎn)換,至于為什么,請(qǐng)看后續(xù)的博客。假如我們?cè)O(shè)計(jì)一個(gè)表示有理數(shù)的class,允許”整數(shù)隱式轉(zhuǎn)換為有理數(shù)似乎很合理“。首先來一個(gè)簡單的實(shí)現(xiàn)。
class Rational { public:Rational(int numerator = 0,int denominator = 1; //允許int-to-Rational隱式轉(zhuǎn)換 int numerator()const;int denominator()const;const Rational operator*(const Rational& rhs)const; //有理數(shù)的乘法... };有理數(shù),我們很自然地為他實(shí)現(xiàn)了乘法的運(yùn)算。我們可以輕松地實(shí)現(xiàn)兩個(gè)有理數(shù)相乘,但是,假如我們想要進(jìn)行混合運(yùn)算呢?在下面的例子中,2在第一個(gè)參數(shù)與第二個(gè)參數(shù)的位置進(jìn)行隱私類型轉(zhuǎn)換。
Rational half(1,2); half = half * 2; //1. 通過編譯 half = 2 *half; //2. 無法通過編譯為什么會(huì)這樣呢?對(duì)于1,編譯器解釋如下,所以很正常地通過了編譯。
operator*(Rational& this,Rational& rhs); //函數(shù)的定義部分 //第一個(gè)參數(shù)是沒辦法改變的,一定是被乘數(shù) half.operator(Rational(2)); //函數(shù)的調(diào)用部分,2被隱式轉(zhuǎn)換為了有理數(shù) //與下面的代碼一致 const Rational temp(2); result = half * temp;編譯器拿到2的時(shí)候,知道operator*()需要一個(gè)Rational,也知道只要調(diào)用Rational的構(gòu)造函數(shù)就能夠變出一個(gè)適當(dāng)?shù)腞ational,所以,它就做了。
結(jié)果就是上面的例子。當(dāng)然,必須存在non-explicit編譯器才會(huì)這么做。
而對(duì)于2中的代碼呢,編譯器首先試著如下解釋
2.operator*(half);很明顯,2.operator()是不存在的東西,所以,編譯器會(huì)嘗試著尋找一個(gè)non-memb operator(),但結(jié)果是:沒有找到。所以只能返回一個(gè)錯(cuò)誤。
很明顯,上面對(duì)于同一個(gè)操作符,卻有了兩種截然不同的結(jié)果,你十分抵觸。然后你就會(huì)義憤填膺地把構(gòu)造函數(shù)修改為explicit。結(jié)果是:兩者一致了,都不支持混合運(yùn)算。但是,我們的目標(biāo)不僅僅在于一致性,我們還希望它支持混合運(yùn)算。那么,請(qǐng)拿出我們的利器:non-member函數(shù)。我們暫時(shí)允許編譯器執(zhí)行隱式類型轉(zhuǎn)換。
class Rational {... }; const Rational operator*(const Rational& lhs,const Rational& rhs); Rational half(1,2); half = half * 2; //通過編譯 half = 2 * half; //通過編譯真的是峰回路轉(zhuǎn)疑無路,千辛萬苦終于找到可行之道。對(duì)于上面的代碼,編譯器會(huì)對(duì)每個(gè)2都轉(zhuǎn)換為Rational(2)。當(dāng)你完成了一天的工作后,最后一個(gè)要操心的問題是:是否需要一個(gè)non-member friend函數(shù)?假如否定的,member的對(duì)立面不是non-member friend函數(shù)。使用了friend,意味著公開自己的所有隱私。這種嚴(yán)重破壞自身隱私的可不是好事,可以參考以下的博客太過親密往往不好——用NON-MEMBER,NON-FRIEND替換MEMBER函數(shù)還有為了更好更方便地活著——愛上PRIVATE.
總結(jié)一下
假如你需要為某個(gè)函數(shù)的所有參數(shù)都進(jìn)行類型轉(zhuǎn)化的時(shí)候,這個(gè)函數(shù)必須是non-member。
member的對(duì)立面不是non-member friend,請(qǐng)慎用friend。
轉(zhuǎn)載于:https://www.cnblogs.com/suimeng/p/4887195.html
總結(jié)
以上是生活随笔為你收集整理的若所有的参数皆需要类型转换——请为此采用non-member函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二、JavaScript语言--JS基础
- 下一篇: bzoj 1572: [Usaco200