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


相关文章
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
109 5
|
2月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
32 1
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
45 3
|
2月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
58 3
|
3月前
|
C++
【C++基础】运算符详解
这篇文章详细解释了C++中运算符的用法,包括算术运算符、赋值运算符、比较运算符和逻辑运算符,以及它们在表达式中的作用和示例。
49 2
|
2月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
30 0
|
3月前
|
C++
C++(十九)new/delete 重载
本文介绍了C++中`operator new/delete`重载的使用方法,并通过示例代码展示了如何自定义内存分配与释放的行为。重载`new`和`delete`可以实现内存的精细控制,而`new[]`和`delete[]`则用于处理数组的内存管理。不当使用可能导致内存泄漏或错误释放。
|
4月前
|
C++
c++学习笔记02 运算符
C++学习笔记,介绍了C++中的运算符,包括基本的加减乘除、求模、前后置递增递减、赋值运算符、比较运算符和逻辑运算符的使用及其注意事项。
47 6
|
5月前
|
NoSQL 编译器 Redis
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
|
5月前
|
NoSQL Redis C++
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决