在C/C++编程中,经常会遇到类型转换的情况。C/C++内置类型允许兼容的类型相互转化。如:

float x = 1.23; //将double1.23转化为int
double y = 22; //将int 22 转化为double

当然,某些不兼容的类型是不能直接相互转换的。如:虽然地址也是用整数表示的,但是从概念上来讲,整数和地址是两码事,因此它们之间的相互转换是非法的:
int * ptr = 10010; //错误;类型冲突

不过,我们可以用强制转换来直接为将指针设为地址10010:

int * ptr = (int *) 10010; //正确;

对于Cat类我们给以定义如下:

class Cat
{
public:
	Cat(string name) : m_name(name), m_age(0){}
	Cat(string name, int age) : m_name(name), m_age(age){}
	
	friend ostream& operator<< (ostream &os, const Cat& myCat);
private:
	string m_name;
	int m_age;

	
};

ostream& operator<< (ostream &os, const Cat& myCat)
{
	os << myCat.m_name << " " << myCat.m_age;
	return os;
}


1、在C++中,允许将接受一个参数的构造函数作为基础,实现类型间的转换。如Cat类的Cat(string name)构造函数:

Cat m = "HelloKitty"; // 以Cat(string name)为基础的隐式转换
cout << m << endl; // 输出m
效果:

当然,如果你想拒绝这种隐式转换的出现,可以将仅接受一个参数的构造函数声明为explicit,这样,就阻止了该构造函数隐式转换的功能,但是其显示转换功能依旧存在:

Cat类:

explicit Cat(string name) : m_name(name), m_age(0){} //加入 explicit关键字
主函数不变,错误提示:



对于没有限定为explicit的单参数构造函数,或者其它参数含有默认值,且无二义性。则会在一下情况下用到以该构造函数为基础隐式转换:

a、将Cat对象初始化为string值时。

b、将double值赋给Cat对象时。

c、将double值传递给接受Cat值的函数时。

d、返回值声明为Cat的函数试图返回double时。

e、在上述每种情况下,使用可转换为double类型的内置类型时(如:int)。


2、转换函数

为了实现Cat到string的转换,我们就需要用到转换函数了。基本的函数定义格式如下:

operator typeName(); // typeName为需要转换成的类型。

如,在Cat类中加入下面的转换函数:

	operator string() const
	{
		return m_name;
	}
这样就可以实现Cat到string的转换了。
注意,一般不允许转换函数对类本身进行修改,故,一般将准换函数定义为const类型。

编译器不承担选择转换函数的责任,因此,隐式转换若存在二义性,转换是不成功的,编译器会进行错误提示。提示如下:


转换函数……额……或者说隐式转换吧……隐式转换最大的缺点是显而易见的:在用户不希望调用类型转换的时候,有意无意地隐式转换了,却很难发现。有两种简单易行的方法来打破这个魔咒:

a、在C++11中让转换函数也能使用explicit关键字来限定,这样限定过的转换函数就只能显示转换了。

b、呵呵……想必大家在不知道有转换函数的时候,都有过这个方法吧。那就是,直接写一个功能与转换函数相似的非转换函数。如:用ToString()函数代替operator string()函数。