【C++之重载类型转换运算符】复数与 double 数相加

简介: 【C++之重载类型转换运算符】复数与 double 数相加

题目要求


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


相关文章
|
20天前
|
编译器 C++
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
26 1
|
4天前
|
安全 程序员 C++
C++一分钟之-重载运算符
【6月更文挑战第21天】C++的运算符重载让程序员能为自定义类型定制运算符行为,增强代码表达力。但要注意清晰性、优先级和返回类型。遵循运算符原有意义,充分测试,并用注释解释非直观设计。示例展示了如何为复数类重载`+`运算符。避免重载内置类型,注意结合性,且慎用隐式转换。重载应提升可读性而非复杂化代码。
16 2
|
7天前
|
C++
C++一分钟之-理解C++的运算符与表达式
【6月更文挑战第18C++的运算符和表达式构成了编程的基础,涉及数学计算、逻辑判断、对象操作和内存管理。算术、关系、逻辑、位、赋值运算符各有用途,如`+`、`-`做加减,`==`、`!=`做比较。理解运算符优先级和结合律至关重要。常见错误包括优先级混淆、整数除法截断、逻辑运算符误用和位运算误解。解决策略包括明确优先级、确保浮点数除法、正确使用逻辑运算符和谨慎进行位运算。通过实例代码学习,如 `(a &gt; b) ? &quot;greater&quot; : &quot;not greater&quot;`,能够帮助更好地理解和应用这些概念。掌握这些基础知识是编写高效、清晰C++代码的关键。
16 3
|
27天前
|
安全 程序员 C语言
从C语言到C++_37(特殊类设计和C++类型转换)单例模式(下)
从C语言到C++_37(特殊类设计和C++类型转换)单例模式
23 5
|
18天前
|
编译器 C++
C++运算符的重载
C++运算符的重载
12 0
|
27天前
|
设计模式 编译器 Linux
从C语言到C++_37(特殊类设计和C++类型转换)单例模式(中)
从C语言到C++_37(特殊类设计和C++类型转换)单例模式
21 0
|
1月前
|
存储 Java
百度搜索:蓝易云【Java语言之float、double内存存储方式】
由于使用IEEE 754标准进行存储,float和double类型可以表示非常大或非常小的浮点数,并且具有一定的精度。然而,由于浮点数的特性,它们在进行精确计算时可能会存在舍入误差。在编写Java程序时,需要注意使
67 0
|
1月前
|
存储 C语言
计算 int, float, double 和 char 字节大小
计算 int, float, double 和 char 字节大小。
27 3
|
8月前
|
存储 C语言
C 语言实例 - 计算 int, float, double 和 char 字节大小
C 语言实例 - 计算 int, float, double 和 char 字节大小。
44 1
|
1月前
|
C#
C# 字节数组与INT16,float,double之间相互转换,字符数组与字符串相互转换,
C# 字节数组与INT16,float,double之间相互转换,字符数组与字符串相互转换,
95 1