看到《深度探索C++对象模型》的第21页,在其谈到C struct在C++中的一个合理用途时,看到了C++中用户定义的转换的运用。因而回头将《C++ Primer》中关于用户定义的转换的一些细节温习了一下。
(1)用户定义的转换的必要性:
我们希望能够在SmallInt对象和其他SmallInt对象或者内置算术类型的对象之间进行加减操作,我们要通过提供6个SmallInt操作符函数来实现对这些操作的支持:
class SmallInt ...{ |
两个成员操作符允许我们加减两个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 ); // 错误参数表 // ... }; |
#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 ); |
extern void calc( double ); Token tok( "constant", 44 ); // 调用 tok.operator int() 吗? 是的 // int --> double 通过标准转换 calc( tok ); |
extern void func( Number ); SmallInt si( 87 ); { // 调用 Number( const SmallInt & ) func( si ); } |