关于构造函数的讨论:
http://blog.163.com/zhoumhan_0351/blog/static/3995422720100250413207/
关于类型转换的讨论
http://blog.163.com/zhoumhan_0351/blog/static/39954227201001934025333/
现在,再引入另一种构造函数转换构造函数
1、转换构造函数
转换构造函数只有一个形参,如
Complex(double r) {real=r;imag=0;}
其作用是将double型的参数r转换成Complex类的对象,将r作为复数的实部,虚部为0。
使用转换构造函数将一个指定的数据转换为类对象的方法如下:
(1) 先声明一个类。
(2) 在这个类中定义一个只有一个参数的构造函数,参数的类型是需要转换的类型,在函数体中指定转换的方法。
(3) 在该类的作用域内可以用以下形式进行类型转换:
类名(指定类型的数据)
不仅可以将一个标准类型数据转换成类对象,也可以将另一个类的对象转换成转换构造函数所在的类对象。如可以将一个学生类对象转换为教师类对象,可以在Teacher类中写出下面的转换构造函数:
Teacher(Student& s){num=s.num;strcpy(name,s.name);sex=s.sex;}
但应注意: 对象s中的num,name,sex必须是公用成员,否则不能被类外引用。用转换构造函数可以将一个指定类型的数据转换为类的对象。但是不能反过来将一个类的对象转换为一个其他类型的数据(例如将一个Complex类对象转换成double类型数据)。如果要这么做,则需要用下面的类型转换函数。
2、类型转换函数
类型转换函数的一般形式为
operator 类型名( )
{实现转换的语句}
operator double( )
{return real;}
也称为类型转换运算符重载函数(或称强制类型转换运算符重载函数)。
在函数名前面不能指定函数类型,函数没有参数。其返回值的类型是由函数名中指定的类型名来确定的(如上面例程中为double)。类型转换函数只能作为成员函数,因为转换的主体是本类的对象。不能作为友元函数或普通函数。它与运算符重载函数相似,都是用关键字operator开头,只是被重载的是类型名。double类型经过重载后,除了原有的含义外,还获得新的含义(将一个Complex类对象转换为double类型数据,并指定了转换方法)。这样,编译系统不仅能识别原有的double型数据,而且还会把Complex类对象作为double型数据处理。
转换构造函数和类型转换运算符有一个共同的功能: 当需要的时候,编译系统会自动调用这些函数,建立一个无名的临时对象(或临时变量)。
在已定义了相应的转换构造函数情况下,将运算符“+”函数重载为友元函数,在进行两个复数相加时,可以用交换律。
#include <iostream>
using namespace std;
class Complex
{public:
Complex( ){real=0;imag=0;} //默认构造函数
Complex(double r){real=r;imag=0;} //转换构造函数
Complex(double r,double i){real=r;imag=i;}//实现初始化的构造函数
friend Complex operator + (Complex c1,Complex c2); //重载运算符
//“+”的友元函数
void display( );
private:
double real;
double imag;
};
Complex operator + (Complex c1,Complex c2)//定义运算符“+”重
//载函数
{return Complex(c1.real+c2.real, c1.imag+c2.imag);}
void Complex∷display( )
{cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;}
int main( )
{Complex c1(3,4),c2(5,-10),c3;
c3=c1+2.5; //复数与double数据相加
c3.display( );
return 0;
}
如果在上面的类中,再加之定义类型转换函数:
operator double( ){return real;} //类型转换函数
则会出问题,因为这时候,编译系统也搞不清楚了,到底是将 c3=c1+2.5; 解释成operator+(c1,Complex(2.5))(调用了转换构造函数),还是解释成类型转换函数的形式呢?