這是Effective C++中第24個原則,即非成員函數能夠完美解決題目中所敘述的情景。
作者以一個有理數類的例子來詮釋本原則所述內容。這個例子大致是這樣的,這個有理數類有一個帶有默認值參數的構造函數,并且也有一個重載的乘法操作符,并且這個重載操作符函數只接受一個有理數類的對象。現在在它參數的位置上放上一個整數,因為構造函數并非顯示,所以它允許將這個整數隱式轉換成該類的類型而參與運算。
但是奇怪的現象來了,因為這個重載操作符是單目操作符,這時出現了一個賦值語句,
這個就是這個單目操作符,oneHalf是一個有理數類對象,2是整數,2可以被隱式轉換成有理數類型。但是下面這個表達式
從邏輯上將實現的功能是一樣的,但是它確報錯,這是為啥呢?那是因為這個的函數原型如下所示:
因為2并不在參數列表中,根本不存在類型轉換,而又因為它要求的是兩個有理數類型參與運算,因此2壓根不符合類型要求,所以會報錯。而這就是所謂的只有被列于參數列表內,這個參數才是隱式轉換的合格參與者。
那這里你一定會冒出一個疑問,既然參數列表里面只有一個參數,那你就改寫一下這個重載操作符的函數唄,這樣兩個參數不就都能進行隱式轉換了嗎?嗯,這個想法是好的,不過類中的重載操作符不支持兩個參數的形式,請看下面的圖示:
但是非成員函數的重載操作符函數卻能支持兩個參數的形式,這樣兩個參數都能進行隱式轉換了。
那么為什么不把非成員函數設成有原函數呢?那是因為有原函數的存在極大地破壞了封裝特性,不符合面向對象的思想,亂用的話會帶來很大麻煩,所以能不用就不用。