一、定义
转换构造函数是将其他类型转化为当前class类型;
反之,就是转换函数。
转换函数的定义格式:
operator type(){
//TODO:
return data;
}
operator 是 C++ 关键字,type 是要转换的目标类型,data 是要返回的 type 类型的数据。
因为要转换的目标类型是 type,所以返回值 data 也必须是 type 类型。既然已经知道了要返回 type 类型的数据,所以没有必要再像普通函数一样明确地给出返回值类型。这样做导致的结果是:类型转换函数看起来没有返回值类型,其实是隐式地指明了返回值类型。
二、用法
#include <iostream>
using namespace std;
class Complex{
private:
double real;
double unreal;
public:
Complex():real(0),unreal(0){}
Complex(double real):real(real){
}
operator double() const{
return this->real;
}
};
int main() {
Complex x(10,20);
double a = x;
double b = (double )x;
return 0;
}
三、注意事项
(1) type 可以是内置类型、类类型以及由 typedef 定义的类型别名,任何可作为函数返回类型的类型(void 除外)都能够被支持。一般而言,不允许转换为数组或函数类型,转换为指针类型或引用类型是可以的。
(2)一个类虽然可以有多个类型转换函数(类似于函数重载),但是如果多个类型转换函数要转换的目标类型本身又可以相互转换(类型相近),那么有时候就会产生二义性。以 Complex 类为例,假设它有两个类型转换函数:
operator double() const { return m_real; } //转换为double类型
operator int() const { return (int)m_real; } //转换为int类型
那么下面的写法就会引发二义性:
Complex c1(24.6, 100);
float f = 12.5 + c1;
编译器可以调用 operator double() 将 c1 转换为 double 类型,也可以调用 operator int() 将 c1 转换为 int 类型,这两种类型都可以跟 12.5 进行加法运算,并且从 Complex 转换为 double 与从 Complex 转化为 int 是平级的,没有谁的优先级更高,所以这个时候编译器就不知道该调用哪个函数了,干脆抛出一个二义性错误,让用户解决。
(3)如果转换构造函数和转换函数同时定义,可能产生二义性:
#include <iostream>
using namespace std;
class Complex{
private:
double real;
double unreal;
public:
Complex():real(0),unreal(0){}
Complex(double real):real(real){
}
Complex(double real,double unreal):real(real),unreal(unreal){}
Complex operator + (const Complex & b){
Complex ans;
ans.real = this->real+b.real;
ans.unreal = this->unreal+b.unreal;
return ans;
}
Complex operator - (const Complex & b){
Complex ans;
ans.real = this->real-b.real;
ans.unreal = this->unreal-b.unreal;
return ans;
}
operator double() const{
return this->real;
}
void display(){
cout<<real<<"+"<<unreal<<"i"<<endl;
}
};
int main() {
Complex x(10,20);
double a = x+1.1;
return 0;
}
如下代码:
double a = x+1.1;
编译器可以理解为:调用转换函数,将x转为10,之后和1.1相加,赋值给a;
也可以理解为:调用转换构造函数,将1.1转换为匿名对象,和x相加(重载),得到匿名的Complex对象,之后调用转换函数,转换为double类型。
二者优先级相同,直接报错,二义性让程序员解决
正确的写法:
double a = (double )x+1.1;
double b = x+Complex(1.1);