(1)用戶定義的轉換的必要性:
我們希望能夠在SmallInt對象和其他SmallInt對象或者內置算術類型的對象之間進行加減操作,我們要通過提供6個SmallInt操作符函數來實現對這些操作的支持:
class SmallInt ...{
friend operator+( const SmallInt &, int );
friend operator-( const SmallInt &, int );
friend operator-( int, const SmallInt & );
friend operator+( int, const SmallInt & );
public:
SmallInt( int ival ) : value( ival ) ...{ }
operator+( const SmallInt & );
operator- ( const SmallInt & );
// ...
private:
int value;
};
兩個成員操作符允許我們加減兩個SmallInt對象。友元全局操作符允許我們在SmallInt對象和內置算術類型的對象之間進行加減操作。之所以只需要6個操作符,是因為任何內置算術類型都可以被轉換為與int型參數相匹配。
如果我們還想支持按位操作符、邏輯操作符、關系操作符和復合賦值操作符,則要求的操作符的數目就變得非常可怕了。我們更希望的,不是提供所有的重載操作符,而是一種將SmallInt類對象自動轉換成int 型對象的方式。
C++提供了一種機制,通過它,每個類都可以定義一組“可被應用在該類型對象上的轉換”。對於SmallInt,我們定義了一個從SmallInt對象到int型的轉換。
class SmallInt ...{
public:
SmallInt( int ival ) : value( ival ) ...{ }
// 轉換操作符
// SmallInt ==> int
operator int() ...{ return value; }
// 沒有提供重載操作符
private:
int value;
};
(2)需要注意的地方:
(a)轉換函數必須是成員函數,它的聲明不能指定返回類型和參數表。
operator int( SmallInt & ); // 錯誤: 不是成員
class SmallInt ...{
public:
int operator int(); // 錯誤: 返回類型
operator int( int = 0 ); // 錯誤參數表
// ...
};
(b)顯式的類型轉換會導致調用轉換函數。(須注意在必要的時候將轉換類型設置為const,只允許對被轉換的類對象進行只讀訪問)
#include "Token.h"
Token tok( "function", 78 );
// 函數型的表示法: 調用 Token::operator SmallInt()
SmallInt tokVal = SmallInt( tok );
// static_cast: 調用 Token::operator tName()
char *tokName = static_cast< char * >( tok );
(c)如果轉換的目標(本例中的double)與轉換函數的類型(本例中的int類型)不完全匹配,但目標類型可以通過標准轉換序列到達,則仍可調用轉換函數。
extern void calc( double );
Token tok( "constant", 44 );
// 調用 tok.operator int() 嗎? 是的
// int --> double 通過標准轉換
calc( tok );
(d)使用構造函數作為轉換函數。
extern void func( Number );
SmallInt si( 87 );
{
// 調用 Number( const SmallInt & )
func( si );
}
當然,可通過在類的構造函數前設置explicit,以禁止將其用來執行隱式轉換。