zoukankan      html  css  js  c++  java
  • 15.C++-操作符重载、并实现复数类

    首先回忆下以前学的函数重载

    函数重载

    • 函数重载的本质为相互独立的不同函数
    • 通过函数名函数参数来确定函数调用
    • 无法直接通过函数名得到重载函数的入口地址
    • 函数重载必然发生在同一个作用域

    类中的函数重载

    • 静态成员函数能与普通成员函数建立重载关系
    • 全局函数和成员函数不能构成重载关系

    操作符重载(operator)

    什么是操作符重载?

    大家都知道,在C里,有'+,-,*,/'这些操作符,且它们的功能就是实现普通变量运算。

    由于C++是面向对象的,遇到的变量大多都是对象,所以优化了C里的操作符,使它们拥有了重载能力.能通过一定方式,使对象能进行'+,-,*,/'等运算.

    操作符的重载是以函数的方式进行.

    操作符重载定义

    操作符重载,通过operator关键字在函数前定义:

    [返回类型]  operator  [需要重载的操作符](函数参数)
    
    {
    
           //......
    
    }
    

    操作符重载有几种方式 : 全局操作符重载函数、全局操作符重载函数

    编译器首先会判断运算的若是对象,就会先从类里寻找成员操作符重载函数,若没找到,就会再去全局里寻找全局操作符重载函数.

    注意事项:

    • 操作符重载不能改变原操作符的优先级
    • 操作符重载不能改变操作数的个数
    • 操作符重载的参数一般设为const class_name &类型(若只设为const class_name,会产生临时对象)
    • 在C++中,有些操作符必须需要有对象支持,所以只能为成员函数.这种被称为一元操作符

     比如赋值(=)、下标([])、下标([])、调用(())和成员访问箭头(->):

    Test t3=t2;   //相当于调用了: Test  t3.operator =(t2);  里面会通过this指针来代替左侧数t3
    • 有些操作符既可以当做成员操作符重载函数,也可以当做全局操作符重载函数,由于函数参数可以多个,便称为二元操作符

    比如加法(+),与(&&),或(||),逗号(,)等:

    以加法(+)为例,当设为全局操作符重载函数时,执行

    Test t3=t1+t2;  //相当于调用了:  Test t3 = operator +(t1,t2); 

    以加法(+)为例,当设为成员操作符重载函数时,执行

    Test t3=t1+t2;  //相当于调用了:  Test t3 =t1.operator +(t2);  //里面会通过this指针来代替左侧数t1
    

    多个重载的操作符重载函数

    由于操作符重载函数带参数,所以可以存在多个相同的操作符重载函数

    例如:

    class Test
    {
    
    double  x;
    
    double  y;
    
    public:
    
    Test operator +(const Test& t);                //实现Test t3=t1+t2
    
    Test operator +(int i);                        //实现Test t3=t1+1
    
    Test operator +(double d);                     //实现Test t3=t1+1.25
    
    //... ...
    
    };
    

      

    初步试验

    1.接下来,来个全局操作符重载函数例子:

    #include "stdio.h"
    
    
    class Test{
    
           int x;
           int y;
    
    public:
           Test(int x=0,int y=0)
           {
                  this->x=x;
                  this->y=y;     
           }
           int getx()
           {
                  return x;
           }
           int gety()
           {
                  return y;
           }
    
           friend Test operator + (const Test& t1,const Test& t2);
                                                     //声明友元函数,可以使用私有成员变量     
    
    };
    
    Test operator + (const Test& t1,const Test& t2)              //重载
    {
           Test ret;
           ret.x=t1.x+t2.x;
           ret.y=t1.y+t2.y;
           return ret;
    }
    
    int main()
    {
           Test t1(1,3);
           Test t2(2,4);
           Test t3= t1 + t2;           // 其实就是调用: Test t3 = operator +(t1,t2);
    
           printf("t3.x:%d  t3.y:%d
    ",t3.getx(),t3.gety());  
    
           Test t4 =operator +(t1,t3);   // t4 =t1 +t3
    
           printf("t4.x:%d  t4.y:%d
    ",t4.getx(),t4.gety());
    
           return 0;
    }
    

    打印结果:

    t3.x:3  t3.y:7
    t4.x:4  t4.y:10
    

      

    2.换成成员操作符重载函数例子:

    #include "stdio.h"
    
    class Test{
    
           int x;
           int y;
    
    public:
           Test(int x=0,int y=0)
           {
             this->x =x;
             this->y =y;
           }
    
           int getx()
           {
                  return x;
           }
    
           int gety()
           {
                  return y;
           }   
    
        Test operator + (const Test& t2)
           {
                  Test ret;
    
                  ret.x = this->x + t2.x;
                  ret.y = this->y + t2.y;
                  return ret;
           }                                 
    };
    
    int main()
    {
           Test t1(1,3);
           Test t2(2,4); 
           Test t3= t1 + t2;           // 其实就是调用: Test t3 =t1.operator +(t2);
    
           printf("t3.x:%d  t3.y:%d
    ",t3.getx(),t3.gety());   
    
           Test t4 =t1.operator +(t3);   // t4 =t1 +t3
    
           printf("t4.x:%d  t4.y:%d
    ",t4.getx(),t4.gety()); 
    
           return 0;
    }

    打印结果:

    t3.x:3  t3.y:7
    t4.x:4  t4.y:10
    

      

    加深理解

    由于C++里,没有复数的慨念,而在刚刚又学习了操作符重载,所以接下来便通过操作符重载来实现复数类

    复数类应该具有

    两个成员

    实部a 、虚部b

    运算操作符

    + - :  结果 = 两个实部进行加减,两个虚部进行加减

    *   :  结果 = (a1+b1)(a2+b2)= (a1*a2 - b1*b2 )+( a2*b1 + a1*b2);

    /   :  结果 =(a1+b1)/(a2+b2)= (a1*a2+b1*b2)/(a2* a2+b2* b2) +(b1*a2-a1*b2)/(a2* a2+b2* b2)

    比较操作符:== ,!=

    赋值操作符: =

    求模成员函数 : 等于a^2+b^2的算术平方根

    所以复数类的操作符重载共有以下几个:

     

    1.写头文件Complex.h:

    #ifndef __COMPLEX_H
    #define __COMPLEX_H
    
    class Complex{
    
    private:
           double a;
           double b;
    
    public:
           Complex(int a=0,int b=0);
           Complex operator + (const Complex& t);
           Complex operator - (const Complex& t);
           Complex operator * (const Complex& t);
           Complex operator / (const Complex& t);
           bool operator == (const Complex& t);
           bool operator != (const Complex& t);
           Complex& operator = (const Complex& t);
    
           double getModulus();
    
           double getA();
           double getB();
    };
    
    #endif
    

    2.写源文件Complex.cpp

    #include "Complex.h"
    #include "math.h"
    
    Complex::Complex(int a,int b)
    {
           this->a = a;
           this->b = b;
    }
    
    Complex Complex::operator + (const Complex& t)
    {
           Complex ret;   
    
           ret.a = a + t.a;
           ret.b = b + t.b;
           return ret;
    }   
    
    Complex Complex::operator - (const Complex& t)
    {
           Complex ret;  
    
           ret.a = a - t.a;
           ret.b = b - t.b;
           return ret;
    }
    
          
    
    Complex Complex::operator * (const Complex& t)
    {
           Complex ret;
           ret.a = (a* t.a - b* t.b );
           ret.b = (t.a *b + a* t.b );     
           return ret;
    }
    
     
    
          
    
    Complex Complex::operator / (const Complex& t)
    {
           Complex ret;
           ret.a = (a* t.a + b* t.b)/(t.a * t.a + t.b * t.b);
           ret.b = (b* t.a - a* t.b)/(t.a * t.a + t.b * t.b);     
           return ret;
    }
    
          
    
    bool Complex::operator == (const Complex& t)
    {
           if((a== t.a)&&(b== t.b))
            return true;
    
           else
            return false;
    }     
    
    bool Complex::operator != (const Complex& t)
    {
           if((a!= t.a)||(b!= t.b))
            return true;
    
           else
            return false;
    }
    
    Complex& Complex::operator = (const Complex& t)
    {
           if(this != &t)
           {
             a = t.a;
             b = t.b;
           }
           return *this;
    }     
    
    double Complex::getModulus()
    {
           return sqrt( a*a + b*b);
    }
         
    
    double Complex::getA()
    {
           return a;
    }     
    
    double Complex::getB()
    {
           return b;
    }     
    

    3.写测试文件test.cpp

    #include "stdio.h"
    #include "Complex.h"
    
    int main()
    {
           Complex t1(1,3);
           Complex t2(2,6);
    
           Complex t3=t1+t2;
    
           printf("t3.a=%f  t3.b=%f
    ",t3.getA(),t3.getB());
    
           printf("t3 Modulus:%f
    ",t3.getModulus());
    
           Complex t4=t3;
    
           printf("t4==t3: %d
    ",t4==t3);
           printf("t4!=t3: %d
    ",t4!=t3);
           printf("t3==t1: %d
    ",t3==t1);
    
           return 0;
    }
    

     

    4.编译运行

    t3.a=3.000000  t3.b=9.000000
    t3 Modulus:9.486833
    t4==t3: 1                                   //为真
    t4!=t3: 0                                   //为假
    t3==t1: 0                                   //为假
    

      

     

  • 相关阅读:
    实现一个微型数据库
    InstallShield 12 制作安装包
    .NET MVC学习笔记(一)
    递归和迭代的差别
    nginx 日志和监控
    c语言中的位移位操作
    Android应用程序绑定服务(bindService)的过程源码分析
    关于js中window.location.href,location.href,parent.location.href,top.location.href的使用方法
    iOS Crash 分析(文二)-崩溃日志组成
    js 字符串转换成数字的三种方法
  • 原文地址:https://www.cnblogs.com/lifexy/p/8635556.html
Copyright © 2011-2022 走看看