运算符重载的宏观思考The Complex Class

  运算符重载是C++中较C语言更加先进和灵活的地方之一,通过运算符重载,使运算符拥有了除了只能完成内置类型的运算操作之外的对于其他自定义类型的运算功能。这使得C++更加灵活,通俗,更加面向对象。

  事实上运算符的重载不过是对函数名为“operator 运算符”的函数的定义,根据所操作的对象的不同,可以分为成员函数和友元函数两种定义方法。

  C++中唯一的三目运算符不能重载,因此所有的运算符重载的形参都不会超过三个,又由于成员函数默认第一个形参必须是自定义类的对象并且默认绑定到*this指针,所以所有的重载为成员函数的运算符重载的形参都不会超过一个。如此说来,左操作数不是自定义的类型的对象是不能和自定义程序的对象运算了?所以我们引进了友元函数,当左操作数不是自定义类型时,可以定义友元函数,由两个形参,左形参是自由类型,右形参是自定义类型,返回自定义类型。这样就可以实现同一类型,不同类型之间的相互运算,并且不受对称性的干扰。算术用算符不存在对称性,有需要时要一一重载。

  友元函数和成员函数并无差别,不过是多了声明和一个左类型对象这些形式上的东西,所以重载为友元函数或成员函数是灵活机动的。但有两个运算符的重载必须重载为友元函数,即输入输出运算符,这是两个包含在标准库istream和ostream中的两个运算符,不仅要重载为友元函数,而且返回值类型必须是istream或ostream,不能反回自定义类型因为二义性引起编译错误。其他除了必须重载为成员函数的赋值运算符(=)下标运算符([])调用运算符(())成员访问运算符(->)以及绝大多数重载为成员函数的复合求值运算符还有改变对象状态的自增自减运算符和解引用运算符,其他运算符的重载是非常自由的。

  以The Complex Class为例

#include <iostream>
#include <stdio.h>
using namespace std;

class Complex {
        double re; //real part of a complex number
        double im; //imaginary part of a complex number
    public:
        Complex() {
            re = 0;
            im = 0;
        }
        Complex(double a,double b = 0) {
            re = a;
            im = b;
        }
        Complex(const Complex& B) {
            re = B.re;
            im = B.im;
        }
        double real() const {
            return re;
        }
        double imag() const {
            return im;
        }
        friend ostream &operator<<(ostream &os,const Complex &c) {            //输出运算符重载为友元函数,返回ostream类型
            os << "(" << c.re << "," << c.im << ")";
            return os;
        }
        friend istream &operator>>(istream &is,Complex &c) {                  //输入运算符重载为友元函数,右形参不加const,返回istream
            char i;
            is >> i >> c.re >> i >> c.im >> i;                                //在输入运算符重载中输入变量
            return is;
        }
        Complex operator+(const Complex& B) {                                 //一般重载,重载为成员函数,右形参为complex
            Complex temp;
            temp.re = re + B.re;
            temp.im = im + B.im;
            return temp;
        }
        Complex& operator+=(const Complex& B) {
            re += B.re;
            im += B.im;
            return *this;
        }
        Complex operator+(double num) {                                       //一般重载,重载为成员函数,右形参为double
            Complex temp;
            temp.re = re + num;
            temp.im = im;
            return temp;
        }
        friend Complex operator+(double num,const Complex & B) {               //重载为友元,左形参为double,返回complex
            Complex temp;
            temp.re = B.re + num;
            temp.im = B.im;
            return temp;
        }
        Complex operator-(const Complex& B) {
            Complex temp;
            temp.re = re - B.re;
            temp.im = im - B.im;
            return temp;
        }
        Complex operator-(double num) {
            Complex temp;
            temp.re = re - num;
            temp.im = im;
            return temp;
        }
        friend Complex operator-(double num,const Complex & B) {
            Complex temp;
            temp.re = num - B.re;
            temp.im = -B.im;
            return temp;
        }
        Complex& operator-=(const Complex& B) {                                          //复合求值运算符,一般重载为成员函数,
            re -= B.re;
            im -= B.im;
            return *this;
        }
        Complex operator*(const Complex& B) {
            Complex temp;
            temp.re = re * B.re - im * B.im;
            temp.im = im * B.re + re * B.im;
            return temp;
        }
        Complex operator*(double num) {
            Complex temp;
            temp.re = re * num;
            temp.im = im * num;
            return temp;
        }
        friend Complex operator*(double num,const Complex & B) {
            Complex temp;
            temp.re = num * B.re;
            temp.im = B.im * num;
            return temp;
        }
        Complex& operator*=(const Complex& B) {
            double temp1 = re, temp2 = im;
            re = temp1 * B.real() - temp2 * B.imag();
            im = temp1 * B.imag() + temp2 * B.real();
            return *this;
        }
        Complex operator/(const Complex& B) {
            Complex temp;
            temp.re = (re * B.re + im * B.im) / (B.re * B.re + B.im * B.im);
            temp.im = (im * B.re - re * B.im) / (B.re * B.re + B.im * B.im);
            return temp;
        }
        Complex& operator/=(const Complex& B) {
            Complex temp;
            temp.re = (re * B.re + im * B.im) / (B.re * B.re + B.im * B.im);
            temp.im = (im * B.re - re * B.im) / (B.re * B.re + B.im * B.im);
            re = temp.re;
            im = temp.im;
            return *this;
        }
        Complex operator/(double num) {
            Complex temp;
            temp.re = re / num;
            temp.im = im / num;
            return temp;
        }
        friend Complex operator/(double num,const Complex & B) {
            Complex temp;
            temp.re = (num * B.re) / (B.re * B.re + B.im * B.im);
            temp.im = ((-num) * B.im) / (B.re * B.re + B.im * B.im);
            return temp;
        }
        bool operator == (const Complex& B) {                                          //关系运算符重载为成员函数,右形参为complex类型
            if (re - B.re < 1e-10 && im - B.im < 1e-10) {
                return true;
            } else {
                return false;
            }
        }
        bool operator != (const Complex& B) {
            if (re - B.re < 1e-10 && im - B.im < 1e-10) {
                return false;
            } else {
                return true;
            }
        }
        bool operator == (double num) {                                             //关系运算符重载为成员函数,右形参为double类型
            if (re - num < 1e-10 && im - 0.0 < 1e-10) {
                return true;
            } else {
                return false;
            }
        }
        bool operator != (double num) {
            if (re - num < 1e-10 && im - 0.0 < 1e-10) {
                return false;
            } else {
                return true;
            }
        }
        friend bool operator == (double num, const Complex& B) {                       //关系运算符重载成友元函数,左形参为double类型
            if (B.re - num < 1e-10 && B.im - 0.0 < 1e-10) {
                return true;
            } else {
                return false;
            }
        }
        friend bool operator != (double num, const Complex& B) {
            if (B.re == num && B.im == 0) {
                return false;
            } else {
                return true;
            }
        }
        Complex operator-() {                                     //取反运算符,改变对象装态,重载为友元函数
            Complex temp;
            temp.re = -re;
            temp.im = -im;
            return temp;
        }
};

用来调试的主程序:

#include<iostream>
#include<string>
#include"source.h"
using namespace std;
void f()
{
  Complex a;
  cout << a << endl;
  Complex b = Complex(1,1.5);
  cout << b << endl;
  Complex c(3.5);
  cout << c << endl;
  c += a;
  cout << c << endl; 

  c = c + a;
  cout << c << endl; 

  c = c + 2.5;
  cout << c << endl; 

  c = 2.5 + c;
  cout << c << endl; 

  c -= a;
  cout << c << endl; 

  c = c - a;
  cout << c << endl; 

  c = c - 2.5;
  cout <<  c << endl; 

  c = 2.5 - b;
  cout << c << endl; 

  c *= b;
  cout << c << endl; 

  c = c * b;
  //cout << c << endl; 

  c = c * 2.5;
  //cout << c << endl; 

  c = 2.5 * c;
  //cout << c << endl; 

  c /= b;
  //cout << c << endl; 

  c = c / b;
  //cout << c << endl; 

  c = c / 2.5;
  //cout << c << endl; 

  c = 2.5 / c;
  //cout << c << endl; 

  c = -b;
  cout << c << endl;

  cout << (a==a) << endl; //output 1
  cout << (a==0.0) << endl; //output 1
  cout << (0.0==a) << endl; //output 1
  cout << (a!=a) << endl; //output 0
  cout << (a!=0.0) << endl; //output 0
  cout << (0.0!=a) << endl; //output 0  

  //cout << a+2.5 << endl;
  //cout << 2.5+a << endl;
  //cout << a+b << endl;
  //c = a+2.5+a + b*2.5*b;
  while (cin >> c)
  {
    cout << c << endl;
    //cout << "(" << c.real() << "," << c.imag() << ")" << endl;
  }
}

int main()
{
  f();

  return 0;
}
时间: 2024-10-07 03:18:14

运算符重载的宏观思考The Complex Class的相关文章

PKU C++程序设计实习 学习笔记4 运算符重载

第四章 运算符重载 4.1 运算符重载的基本概念 1. 运算符 2. 自定义数据类型与运算符重载 C++提供了数据抽象的手段:用户自己定义数据类型 -- 类 ? 调用类的成员函数->操作它的对象 类的成员函数->操作对象时,很不方便 ? 在数学上,两个复数可以直接进行+/-等运算 Vs. 在C++中,直接将+或-用于复数是不允许的 3. 运算符重载 对抽象数据类型也能够直接使用C++提供的运算符 ? 程序更简洁 ? 代码更容易理解 运算符重载 ? 对已有的运算符赋予多重的含义 ? 使同一运算符

[转]C++之运算符重载(1)

在前一节中曾提到过,C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的.这一系列我将主要讲解C++中有关运算符重载方面的内容.在每一个系列讲解之前,都会有它的一些基础知识需要我们去理解.而运算符重载的基础就是运算符重载函数.所以今天主要讲的是运算符重载函数. 1.运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用域不同类型的数据导致不同行为的发生.比如 1 int i;2 int i1=10,i2=10;3 i=i1+i2;4 std::co

c++运算符重载1

在前一节中曾提到过,C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的.这一系列我将主要讲解C++中有关运算符重载方面的内容.在每一个系列讲解之前,都会有它的一些基础知识需要我们去理解.而运算符重载的基础就是运算符重载函数.所以今天主要讲的是运算符重载函数. 1.运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用域不同类型的数据导致不同行为的发生.比如 1 int i; 2 int i1=10,i2=10; 3 i=i1+i2; 4 std:

复数中的运算符重载(续)

输入代码: /* *Copyright (c)2015,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:sum123.cpp *作 者:林海云 *完成日期:2015年5月11日 *版 本 号:v2.0 * *问题描述:在复数类中的运算符重载基础上 (1)再定义一目运算符 -,-c相当于0-c. (2)定义Complex类中的<<和>>运算符的重载,实现输入和输出,改造原程序中对运算结果显示方式,使程序读起来更自然. *程序输入:按要求输入两个复

C++的运算符重载--思考1

学习C++ 我们最深刻的体会就是C++不像那个C同学,是那样的单纯,我们表面上一看就透,是啥就是傻.C++中所有的东西都是为面向对象而设计的,所以不免有些黑盒之类到的思想,就是很多表面的东西,在内部是经过复杂的封装的,所以这个C++同学已经别社会污染,变得城府很深了,我们要想了解这位C++同学,就必须从他的外表之下去偷窥他内心那单纯的性格,只有这样才能看到它的内心世界! 今天我想讨论一下运算符重载,其实说白了就是一个函数重载,只是这个函数的名字有点怪而已.看这一点就可以体现出C++ 同学的城府很

C++ Complex + - += -+ &lt;&lt;运算符重载

/* 提供了加减运算符重载的复数类头文件.关于传递引用和传递值,使用const 和不使用const,关于指针成员的使用需要继续学习...同理可以写出乘除法,共轭复数,绝对值, 等其他运算符重载. */ #ifndef _COMPLEX_H_#define _COMPLEX_H_#include<iostream>using namespace std;class Complex{public: //构造函数 Complex(double r = 0, double i = 0):re(r),

C++ 关于运算符重载

转载来源:http://c.biancheng.net/cpp/biancheng/view/216.html 重载运算符的函数一般格式如下:    函数类型 operator 运算符名称 (形参表列)    {        // 对运算符的重载处理    } 例如,想将”+”用于Complex类(复数)的加法运算,函数的原型可以是这样的:    Complex operator+ (Complex& c1, Complex& c2);在上面的一般格式中,operator是关键字,是专门

C++:运算符重载函数之成员运算符重载函数

5.2.3 成员运算符重载函数 在C++中可以把运算符重载函数定义为某个类的成员函数,称之为成员运算符重载函数. 1. 定义成员运算符重载函数的语法形式 (1)在类的内部,定义成员运算符重载函数的格式如下: 函数类型 operator 运算符(形参表) {       函数体 } (2)成员运算符重载函数也可以在类中声明成员函数的原型,在类外定义. 在类的内部,声明成员运算符重载函数原型的格式如下: class X{      ...      函数类型 operator运算符(参数表); };

C++复数运算符重载(+与&lt;&lt;)

Description 定义一个复数类Complex,重载运算符"+",使之能用于复数的加法运算与输出操作.(1)参加运算的两个运算量可以都是类对象,也可以其中有一个是实数,顺序任意.例如,c1+c2,d+c1,c1+d均合法(设d为实数,c1,c2为复数).(2)输出的算数,在复数两端加上括号,实部和虚部均保留两位小数,如(8.23+2.00i).(7.45-3.40i).(-3.25+4.13i)等.编写程序,分别求两个复数之和.整数和复数之和,并且输出. 请在下面的程序段基础上完