题目要求
请编写程序,处理一个复数与一个 double 数相加的运算,结果存放在一个 double 型的变量 d1 中,输出 d1 的值,再以复数形式输出此值。定义 Complex(复数)类,在成员函数中包含重载类型转换运算符:
operator double() {return real;}
——谭浩强的《C++面向对象程序设计》第4章习题第6小题
不同类型数据间的转换
1.标准类型数据间转换
包括隐式变换和显式变换。
隐式变换(编译系统自动完成):
例如:
int i = 7; // 定义一个整型变量 i = 1.2 + i; // 编译系统自动将 i 从整型转为 double 型
显式变换:
格式:
(类型名) 数据
比如:
i = (int)10.24 // 将 10.24 从 double 型转为 int 型,并赋值给i
2.其他类型的数据转换成一个类的对象
转换构造函数可以将其他类型的数据转换成一个类的对象。
例如:
Complex(double r){real = r; imag = 0;} // 将 double 型参数 r 转换为 Complex 型对象,将 r 作为复数的实部,虚部为0
转换构造函数只有一个参数,参数的类型是需要转换的类型。
在该类的作用域内,可以进行类型转换:
类名(指定类型的数据)
例如:
Complex c = Complex(3.6) // 将3.6转换为 Complex 类型,并赋值给c
由题意,一个复数与一个 double 数相加,可以先把 double 数据转换成 Complex 类对象,然后调用运算符 “+” 重载函数,使得两个 Complex 类对象相加,再通过类型转换函数,将结果转为 double数据,再赋值给 d1。
3.一个类的对象转换成另一类型的数据
类型转换函数可以将一个类的对象转换成另一类型的数据。
类型转换函数的一般形式:
operator 类型名() {实现转换的语句}
函数名为 " operator 类型名 "
在函数名前面不能指定函数的类型
函数没有参数
函数返回值由函数名中指定的类型名来确定
类型转换函数只能作为成员函数,因为转换的主体是本类的对象,不能作为友元函数或普通函数。
在已定义了相应的转换构造函数的情况下,将运算符 “+” 函数重载为友元函数,在进行两个复数相加时,可以用交换律。
在程序中不必显式地调用类型转换函数,它是自动被调用的,即隐式调用。
由题意,一个复数与一个 double 数相加,可以先用调用类型转换函数,把复数转成 double 类型,然后与另一个 double 数相加,得到 double 型数据。
如果采用这种方法,则不需要定义运算符 “+” 的重载函数,编译系统在执行复数与 double 数相加时,自动调用转换构造函数,将复数转成 double 型数据,然后两个 double 数相加。
在 Complex 类中定义类型转换函数:
operator double() {return real;} // 函数返回 double 型变量 real 的值
程序
/* ************************************************************************* @file: main.cpp @date: 2020.12.4 @author: Xiaoxiao @brief: 复数与 double 数相加 @blog: https://blog.csdn.net/weixin_43470383/article/details/110633035 ************************************************************************* */ #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; } // 定义类型转换函数 operator double() { return real; } void display(); private: double real; double imag; }; void Complex::display() { cout << "(" << real << ", " << imag <<")"<< endl; } int main() { Complex c(3, 4), c2; double d1; d1 = c + 10.24; // double 类与 Complex 类相加 cout << "d1 = " << d1 << endl; c2 = Complex(d1); // double 类转换成 Complex 类 cout << "c2 = "; c2.display(); system("pause"); return 0; }
运行结果
输出:
d1 = 13.24
c2 = (13.24, 0)
假如在程序中加入重载运算符 “+” 的友元函数,先调用类型转换函数,将10.25转为复数,然后两个复数相加,再将 Complex 类转换成 double 型数据。
/* ************************************************************************* @file: main.cpp @date: 2020.12.4 @author: Huo Xiaoxiao @number: 201821030208 @brief: 复数与 double 数相加 @blog: https://blog.csdn.net/weixin_43470383/article/details/110633035 ************************************************************************* */ #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; } // 定义类型转换函数 operator double() { return real; } // 声明重载运算符 "+" 的友元函数 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 <<")"<< endl; } int main() { Complex c1(3, 4), c2; double d1; c2 = c1 + 10.24; // double 类与 Complex 类相加 cout << "c2 = "; c2.display(); d1 = c2; // Complex 类转换成 double 类 cout << "d1 = " << d1 << endl; system("pause"); return 0; }
编译程序,会出现错误:
1> h:\project\c++\class\zy_0\zy_0\main.cpp(48): error C2666: “operator +”: 2 个重载有相似的转换 1> h:\project\c++\class\zy_0\zy_0\main.cpp(34): note: 可能是“Complex operator +(Complex,Complex)” 1> h:\project\c++\class\zy_0\zy_0\main.cpp(48): note: 尝试匹配参数列表“(Complex, double)”时
原因是程序出现二义性,不知道是先把复数变成 double 型,还是先把 double 型转成复数,所以类型转换函数和运算符 “+” 重载函数只能留一个。