在C和C + +中,如果编译器看到一个表达式或函数调用使用了一个不合适的类型,它经常
会执行一个自动类型转换。在C + +中,可以通过定义自动类型转换函数来为用户定义类型达到
相同效果。这些函数有两种类型:特殊类型的构造函数和重载的运算符。
11.6.1 构造函数转换
如果我们定义一个构造函数,这个构造函数能把另一类型对象(或引用)作为它的单个参
数,那么这个构造函数允许编译器执行自动类型转换。如下例:
class One{
public:
One(){}
};
class Two{
public:
Two(const One&){}
};
void f(Two t){
}
main(){
One one;
f(one); //Wants a Two, has a One
}
当编译器看到f( )以为对象o n e参数调用时,编译器检查f( )的声明并注意到它需要一个t w o
对象作为参数。然后,编译器检查是否有从对象one 到t w o的方法。它发现了构造函数
t w o : : t w o ( o n e ),t w o : : t w o ( o n e )被悄悄地调用,结果对象t w o被传递给f( )。
在这个情况里,自动类型转换避免了定义两个f( )重载版本的麻烦。然而,代价是隐藏了
构造函数对t w o的调用,如果我们关心f( )的调用效率的话,那就不要使用这种方法。
• 阻止构造函数转换
有时通过构造函数自动转换类型可能出现问题。为了避开这个麻烦,可以通过在前面加关
键字explicit (只能用于构造函数)来修改构造函数。上例类t w o的构造函数作了修改,如下:
class One{
public:
One(){}
};
class Two{
public:
Two(const One&){}
};
void f(Two t){
}
main(){
One one;
//f(one); //no auto conversion allowed
f(Two(one)); //OK user perform conversion
}
通过使类t w o的构造函数显式化,编译器被告知不能使用那个构造函数(那个类中其他非
显式化的构造函数仍可以执行自动类型转换)执行任何自动转换。如果用户想进行转换必须写
出代码。上面代码f ( t w o ( O n e ) )创建一个从类型O n e到t w o的临时对象,就像编译器在前面版本中
做的那样。
11.6.2 运算符转换
第二种自动类型转换的方法是通过运算符重载。我们可以创建一个成员函数,这个函数通
过在关键字o p e r a t o r后跟随想要转换到的类型的方法,将当前类型转换为希望的类型。这种形
式的运算符重载是独特的,因为没有指定一个返回类型——返回类型就是我们正在重载的运算
符的名字。这儿有一个例子:
class Three{
int i;
public:
Three(int I = 0, int = 0) : i(I){}
};
class Four{
int x;
public:
Four(int X) : x(X){}
operator Three(){ return Three(x); }
};
void g(three){}
void main(){
Four four(1);
g(four);
g(1);
}
用构造函数技术,目的类执行转换。然而使用运算符技术,是源类执行转换。构造函数技
术的价值是在创建一个新类时为现有系统增加了新的转换途径。然而,创建一个单一参数的构
造函数总是定义一个自动类型转换(即使它有不止一个参数也是一样,因为其余的参数将被缺
省处理),这可能并不是我们所想要的。另外,使用构造函数技术没有办法实现从用户定义类
型向内置类型转换,这只有运算符重载可能做到。
posted on 2009-03-06 19:07
李阳 阅读(1209)
评论(0) 编辑 收藏 引用 所属分类:
C++