题目要求

请编写程序,处理一个复数与一个 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;
}

运行结果

Java 两个double相加 两个double类型相加_多态


输出:

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;
}

编译程序,会出现错误:

Java 两个double相加 两个double类型相加_Java 两个double相加_02

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 型转成复数,所以类型转换函数和运算符 “+” 重载函数只能留一个。