题目要求
请编写程序,处理一个复数与一个 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:
*************************************************************************
*/
#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:
*************************************************************************
*/
#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 型转成复数,所以类型转换函数和运算符 “+” 重载函数只能留一个。