对定制的“类型转换函数”保持警觉

单自变量constructors是指能够以单一自变量成功调用的constructors。如此的constructors可能声明拥有单一参数,也可能声明拥有多个参数,除第一个参数之外都有默认值。
class Name
{
Name(const string& s)//可以把string转换为Name
....
}

class Rational
{
Rational(int number = 0, int den = 0)//可以把int 转换为Rational
....
}

隐式类型转换操作符,是一个拥有奇怪名称的member function:关键词operator之后加上一个类型名称。不能为此函数指定返回值类型,因为其返回值类型基本上已经表现于函数名称上了。
class Rational
{
public:
.....
operator double() const;//将Rational 转换为double
};

Ration r(1,2);
double d = 0.5 * r;//将r转换为double ,然后再执行乘法运算

在执行
Rational r(1,2);
cout<<r;
我们并没有定义该类的<<操作,但是编译器发现,只要将r转换成double,该语句是可以正常执行的,因此它会进行相应的隐式转换,而这种转换并不是我们想要的。
解决办法就是以一个对等的函数来取代类型转换操作符。
class Rational 
{
public:
....
double asDouble() const;
};

Ration r(1,2);
cout<<r;//此时,因为没有定义<<操作,也没有operator double() 函数,程序会报错
cout<<r.asDouble();//在osg中节点类均采用了这种方式


template<class T>
class Array
{
public:
Array( int lowBound,  int highBound);
Array( int size);
T& operator[]( int index);
...
};

考虑一个用来对Array<int> 对象进行比较动作的函数,以及一小段代码:
bool operator == ( const Array<int>& lhs, const Array<int>& rhs);
Array<int> a(10);
Array<int> b(10);
....
for( int i=0; i<10; ++i)
if( a == b[i] )//此处应该是a[i]才对
{ do something; }
else
{ do something else; }

此时编译器会产生如下的代码:
for( int i=0; i<10; ++i)
if( a == static_cast< Array<int> >(b[i]);

关键词explicit可以解决隐式类型转换带来的问题。只需将constructor声明为explicit即可。但是显示的转换仍然是可以的。

C++中有一条规则:没有任何一个转换程序可以内含一个以上的“用户定制转换行为”。我个人的理解是:编译器不能两次同时调用隐式类型转换函数。
解决办法:
template<class T>
class Array()
{
public:
class ArraySize(
{
AraaySize( int numElements) : theSize( numElements) {}
int size( ) const { return theSzie ; }
private:
int theSize;
};

Array( int lowBound, int highBound);
Array( ArraySize size);
...
};
将类如此改写之后,if( a == b[i] )中的b[i]则不能先调用隐式转换成ArraySize,然后再调用Array(int size)对象。因为这将调用两个用户定制转换行为,程序是禁止的。
类似ArraySize这样的classes, 往往被称为proxy classes,因为它的每一个对象都是为了其他对象而存在的,好像其他对象的代理人一般。ArraySize对象只是“用来
指定Array大小”的整数替身而已,Proxy objects让你得以超越外观形式。

More Effective C++ ----6th

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值