转换用户定义的类类型,必须由用户告知。用户告知的方式就是定义含一个参数的构造函数。 例如,下面的代码中定义了学生类的构造函数: class Student { public: Student(char*); }; void fn(Student s); int main() { fn("Jenny"); return 0; } 这里Student(char*)构造函数同时也在告知,如何将char*转换成一个Student对象。如果有重载函数fn(char*),则调用fn("Jenny")马上匹配了事。但就是因为没有这样的重载函数,所以C++对所有fn函数进行类型转换试探,包括构造函数。 因为为Student(char*)的构造函数,又有fn(Student& s)函数,于是fn("Jenny")便被认为是fn(Student("Jenny")),最终予以匹配。把构造函数用来从一种类型转换为另一种类型,这是C++从类机制中获得的附加性能。但要注意下面两点: (1)只会尝试含有一个参数的构造函数; (2)如果有二义性,则放弃尝试。例如: class Student { public: Student(char* pName = "no name"); }; class Teacher { public: Teacher(char* pName = "no name"); }; void addCourse(Student s); void addCourse(Teacher t); int main() { addCourse("Prof.Dingleberry"); // error:二义性 return 0; } 改正的方法是,只要显式转换一下: addCourse(Teacher("Prof.Dingleberry")); 一个类型转换函数的例子: #include <iostream.h> class date { public: date(int a, int b); operator int();//类型转换函数 void output(void); date &operator=(int);//重载等号运算符 private: int str; int mimg; }; date::date(int a, int b) //构造函数 { str = a; mimg = b; } date::operator int() //类型转换函数,将date类型转换为int类型 { return str; } void date::output(void) { cout << str << " " << mimg << endl; return; } date &date::operator=(int i) { str=i; mimg=1000; return *this; } int main(void) { date da(100, 200); date c(0,0); //int c; c = 55 + da; c.output();//结果为 155 1000 //cout<<c;//结果为 155 return 0; } 其中main函数中的c = 55 + da;若定义c为int型(如注释),则编译器首先判断等号左端的c为int类型,则须将等号右端的da用类型转换函数转换为int型,然后相加,返回int型结果。若定义c为date类型,则须将等号右端的55+da转换为date类型,但是又没有转换构造函数把常量55转为date型,也没有重载+号运算符,只能用类型转换函数将da转为int型,55+da的结果就是一个int型。但等号右端的c却为date型,等号两端类型不匹配,所以就通过重载的=号运算符,隐式调用c.operator(55+100),由于重载的=号运算符返回是一个引用类型,所以c.operator(55+100)的结果就是还是date类型的c。本程序中的c = 55 + da的调用过程是:c.operator(55+(da.operator int())). 再写一个转换构造函数的例子 #include <iostream.h> class date { public: date(int a, int b); date(int n); //转换构造函数 friend date operator+(const date &,const date &); //重载 + void output(void); date &operator=(int); private: int str; int mimg; }; date::date(int a, int b) //构造函数 { str = a; mimg = b; } date :: date(int n) //转换构造函数 { str = n; mimg = 0; } date operator +(const date &a,const date &b) //重载 + { return date(a.str + b.str, a.mimg + b.mimg); } void date::output(void) { cout << str << " " << mimg << endl; return; } int main(void) { date da(100, 200); date c(0,0); c = 55 + da; c.output(); return 0; } main函数在执行c=55+da时,判断c为date类型,所以(55+da)也应为data类型。通过转换构造函数将根据55,创建一个date类型的一个临时对象,然后通过+号运算符重载函数,计算da与临时对象的和。但这里需要注意,+号运算符重载函数里的参数必须是const类型。因为非const的引用只能绑定同类型的对象,const则可以绑定能互相转换的类型。即隐式转换不会被用于非const的引用参数。 一个二义性的例子: #include <iostream.h> class date { public: date(int a, int b); date(int n); //转换构造函数 operator int(); //类型转换函数 friend date operator+(const date &,const date &); //重载 + void output(void); date &operator=(int); private: int str; int mimg; }; date::date(int a, int b) //构造函数 { str = a; mimg = b; } date :: date(int n) //转换构造函数 { str = n; mimg = 0; } date::operator int() //类型转换函数 { return str; } date operator +(const date &a,const date &b) //重载 + { return date(a.str + b.str, a.mimg + b.mimg); } void date::output(void) { cout << str << " " << mimg << endl; return; } int main(void) { date da(100, 200); date c(0,0); c = 55 + da; c.output(); return 0; } 如果写成这样,那么main函数在执行c=55+da的时候就会出现二义性,不知道该调用类型转换函数还是调用转换构造函数了。
|
|