1、类型转换构造函数的概念
类型转换构造函数是这样一种构造函数:它只有一个参数,而且它不是属于复制构造函数的构造函数,一般就可以把它看作是转换构造函数。
2、类型转换构造函数的作用
- 定义转换构造函数的目的是实现类型的自动转换。
- 当需要的时候,编译系统会自动调用转换构造函数,建立
一个无名的临时对象(或临时变量)。
3、类型转换构造函数什么时候被调用?
(1)发生在初始化语句。
上述情况是指在定义一个类类型的变量且使用一个对象对其进行显式初始化时,使用的对象的类型与定义的类型不匹配。
发生过程: 编译器会查看该类型是否有匹配类型转换函数可用。如果有,编译器会创建一个该类类型的对象,并且则将等号右边(用于初始化的对象)当做参数传递给转换构造函数来初始化创建的对象。
注意:由于编译器优化的作用,这种情况编译器不会创建临时对象。这种情况其实也可以理解为这个类型转换构造函数就是一个普通的构造函数,只是说此时的函数确实符合转换构造函数的特征。
(2)发生在赋值语句。
上述情况是指 定义一个类类型的变量后,对其进行赋值,但是等号右边的类型与其不匹配时。
发生过程:编译器会查看该类型是否有匹配的类型转换函数可用。如果有,编译器会创建一个该类型的临时对象(也可以叫做临时变量),并将等号右边(用于初始化的对象)作为参数传递给转换构造函数来初始化创建的临时对象,然后将这个临时变量赋值给等号左边的变量。
注意:这种情况才是真正的类型转换函数,它确实通过建立一个临时对象,达到了类型转换的效果。
总之,就是遇见等号两边不匹配时(该等号可能是赋值语句,也可能是初始化语句),编译器会查看是否存在类型转换构造函数,如果有,则进行类型装换,使得程序能够正常进行。如果没有,编译器则会报错。
3、类型转换构造函数的举例
//例1: 隐式转换
class Complex {
public:
double real, imag;
Complex( int i) {//类型转换构造函数
cout << "IntConstructor called" << endl;
real = i; imag = 0;
}
Complex(double r,double i) {real = r; imag = i; }
};
int main ()
{
Complex c1(7,8);
Complex c2 = 12;// 属于情况一:编译器先创建一个Complex对象c2,然后将12传递给转换构造函数对c2变量进行初始化。
c1 = 9; // 属于情况二:9被自动转换成一个临时Complex对象,然后将该对象赋值给c1。这里的转换属于隐式的转换。
cout << c1.real << "," << c1.imag << endl;
return 0;
}
//例2:显式转换
class Complex {
public:
double real, imag;
explicit Complex( int i) {//显式类型转换构造函数
cout << "IntConstructor called" << endl;
real = i; imag = 0;
}
Complex(double r,double i) {real = r; imag = i; }
};
int main () {
Complex c1(7,8);
Complex c2 = Complex(12);
c1 = 9; // error,9不能被自动转换成一个临时Complex对象,不支持隐式的转换。所匹配的转换构造函数不支持隐式转换。
c1 = Complex(9) //正确,这里,complex(9)先创建一个临时的Complex对象,然后调用转换构造函数将其初始化,即:显示的将9转换为一个Complex对象。
cout << c1.real << "," << c1.imag << endl;
return 0;
}
//显式类型转换构造函数,不会隐式的调用类型转换构造函数,必须显式的调用