当前位置: 首页 > article >正文

C++运算符重载实例

一、重载双目运算符

例1 重载算数运算符,用于两个字符串的比较

注:
1)比较规则:调用int strcmp(const char *str1, const char *str2)函数,按照ASCII码表从首字母开始比较str1和str2的值。
2)因为算数运算符需要两个对象(左、右各一个操作数),因此只能用友元函数形式。
3)运算符重载可以嵌套使用。

#include <iostream>
#include <sstream>
#include <string>

using namespace std;
class String
{
public:
    String( ){p=NULL;}
    String(char *str);                              //重载构造函数,为类型为字符串指针的数据成员分配空间
    ~String();                                      //析构函数,释放空间
    friend string operator>(String &s1, String &s2);  
    friend string operator<(String &s1, String &s2);
    friend string operator==(String &s1, String &s2);
    friend string operator>=(String &s1, String &s2);
    friend string operator<=(String &s1, String &s2);
    friend string operator!=(String &s1, String &s2);
    void display( );
private:
    char *p;
};

String::String(char *str)
{
p = new char[strlen(str)+1];
strcpy(p, str);
}

void String::display( )
{
    cout<<"The string is: "<<p<<endl;
}

String::~String()
{
    delete p;
}

string operator>(String &s1,String &s2)   //strcmp按照ASCII码表,从字符串首字母开始依次比较,直至有差异;
{
    if(strcmp(s1.p,s2.p)>0)
        return "YES";
    else
        return "NO";
}
string operator<(String &s1,String &s2)
{
    if(strcmp(s1.p,s2.p)<0)
        return "YES";
    else
        return "NO";
}
string operator==(String &s1, String &s2)
{
    if(strcmp(s1.p,s2.p)==0)
        return "YES";
    else
        return "NO";
}

string operator>=(String &s1, String &s2)
{
    if((s1<s2) == "YES")    //运算符重载嵌套
        return "NO";
    else
        return "YES";
}
string operator<=(String &s1, String &s2)
{
    if((s1>s2) == "YES")    //运算符重载嵌套
        return "NO";
    else
        return "YES";
}
string operator!=(String &s1, String &s2)
{
    if((s1==s2) == "YES")    //运算符重载嵌套
        return "NO";
    else
        return "YES";
}



int main()
{
    String s1("a");
    String s2("b");
    s1.display( );
    s2.display( );
    
    string a1 = "NULL";
    a1 = (s1>s2);
    cout<<"If s1 > s2  established? The answer is: "<<a1<<endl;
    a1 = (s1<s2);
    cout<<"If s1 < s2  established? The answer is: "<<a1<<endl;
    a1 = (s1==s2);
    cout<<"If s1 == s2  established? The answer is: "<<a1<<endl;
    a1 = (s1>=s2);
    cout<<"If s1 >= s2  established? The answer is: "<<a1<<endl;
     a1 = (s1<=s2);
    cout<<"If s1 <= s2  established? The answer is: "<<a1<<endl;
     a1 = (s1!=s2);
    cout<<"If s1 != s2  established? The answer is: "<<a1<<endl;
    return 0;    
}

例2 重载复合赋值运算符+=
#include <iostream>
using namespace std;

class Complex{
public:
    Complex() 
    {
        real=0;
        imag=0;
    }
    Complex(double r,double i) 
    {
        real=r;
        imag=i;
    }
    Complex operator += (const Complex & c);
    void display( );
private:
    double real;
    double imag;
};

Complex  Complex::operator += (const Complex & c)
{
    real += c.real; //this->real += c.real;
    imag += c.imag; //this->imag += c.imag;
    return *this;
}
void Complex::display( )
{
    cout<<"("<<real<<","<<imag<<"i)"<<endl;
}

int main( )
{
    Complex c1(3,4),c2(-3,-4);
    c1+=c2; //相当于c1.operator+=(c2);
    cout<<"c1 = ";
    c1.display();
    return 0;
}

二、重载单目运算符

当使用成员函数方式作为单目运算符的重载函数时,由于成员函数已将本类对象作为一个默认参数(class *this),且单目运算符仅一个操作数,因此入参直接省略;所以,不用友元函数形式了。

例3 重载~取反运算符,实现分数类对象的倒数
#include <iostream>
#include <cmath>
using namespace std;

class CFraction
{
private:
    int nume; // 分子 numerator  
    int deno; // 分母 denominator
public:
    CFraction(int nu=0,int de=1):nume(nu),deno(de) {}   //构造函数
    CFraction operator+(const CFraction &c);            //+双目运算符重载函数,实现分数相加
    CFraction operator-(const CFraction &c);            //-双目运算符重载函数,实现分数相减
    CFraction operator~();                              //-单目运算符重载函数,实现分数取反
    void simplify();
    void display();

};


CFraction CFraction:: operator+(const CFraction &c)     //分数加法,双目+运算符重载
{
    CFraction t;
    t.nume=nume*c.deno+c.nume*deno; //通分 分子
    t.deno=deno*c.deno;             //通分 分母
    t.simplify();
    return t;
}


CFraction CFraction:: operator-(const CFraction &c)     //分数减法,双目-运算符重载
{
    CFraction t;
    t.nume=nume*c.deno-c.nume*deno; //通分 分子
    t.deno=deno*c.deno;             //通分 分母
    t.simplify();
    return t;
}
CFraction CFraction:: operator~()                       //分数取倒数,单目~运算符重载
{
    CFraction x;
    x.nume=deno;
    x.deno=nume;
    return x;
}

void CFraction::simplify()
{
    int m,n,r;
    m=fabs(nume);   //分子 取绝对值
    n=fabs(deno);   //分母 取绝对值
    while(m%n)    // 求m,n的最大公约数r
    {
       r=m%n;
        m=n;
        n=r;        //r即为最大公约数
    }
    deno/=n;        // 通分 分母
    nume/=n;        // 通分 分子
    if (deno<0)     // 将分母转化为正数
    {
        deno=-deno;
        nume=-nume;
    }
}

void CFraction::display()
{
    cout<<nume<<"/"<<deno<<endl;  
}


int main()
{
    CFraction CF1(1,2),CF2(1,3),CF3,CF4,CF5,CF6;
    CF1.display();
    CF2.display();
    cout<<"=============="<<endl;
    CF6 = CF1 + CF2;        //CF6 = CF1.operator+(CF2);
    CF6.display();
    cout<<"=============="<<endl;
    CF3 = CF2 - CF1;        //CF3 = CF2.operator-(CF1);
    CF3.display();
    CF4 = CF1 - CF2;        //CF4 = CF1.operator-(CF2);
    CF4.display();
    cout<<"=============="<<endl;
    CF5 = ~CF4;             //CF5 = CF4.operator~();
    CF5.display();
    
    return 0;    
}

例4 重载前置++运算符,实现时钟加一秒
#include <iostream>
#include <cmath>
using namespace std;

class Time
{
public:
    Time( ){hour=0;minute=0;sec=0;}
    Time(int h,int m,int s): hour(h),minute(m),sec(s){ }
    Time operator++( );
    void display( )
    {
        cout<<hour<<":";
        cout<<minute<<":";
        cout<<sec<<endl;
    }
private:
    int hour;
    int minute;
    int sec;
};

Time Time::operator++( )
{
    if((++sec)>=60)
    {
        sec-=60;
        ++minute;
    }
    if((minute)>=60)
    {
        minute-=60;
        ++hour;
    }
    if((hour)>=24)
    {
       hour = minute =sec =0;
    }
    return *this;        //注意:返回当前最新对象
}

int main()
{
    Time t1(22,33,59);
    t1.display( );
    ++t1;
    t1.display( );
    return 0;    
}

例5 重载后置++运算符(特殊)

注意:前置++与后置++在声明、定义时的形式不同

Time operator++( );    //前置++
Time operator++(int);  //后置++

完整代码:

#include <iostream>
#include <cmath>
using namespace std;

class Time
{
public:
    Time( ){hour=0;minute=0;sec=0;}
    Time(int h,int m,int s): hour(h),minute(m),sec(s){ }
    Time operator++(int);   //C++特别规定,如果后置++则需要在入参中,明确标出参数类型
    void display()   
    {
        cout<<hour<<":";
        cout<<minute<<":";
        cout<<sec<<endl;
    }
private:
    int hour;
    int minute;
    int sec;
};

Time Time::operator++(int)          //后置++
{
    Time temp(*this);    //先复制当前对象到temp
    sec++;               //后置++
    if(sec>=60)
    {
        sec-=60;         //sec = sec-60
        ++minute;}
    if(minute>=60)
    {
        minute-=60;
        ++hour;}
    if(hour>=24)
    {
        hour-=24;
        hour = minute =sec =0;
    }
    cout<<temp.sec<<endl;   //之前对象的sec
    cout<<this->sec<<endl;  //当前对象的sec
    return temp;            //注意:返回之前的对象,而不是当前对象!
}

int main()
{
    Time t1(22,33,56);
    t1.display( );
    t1++;
    t1.display( );
    t1++;
    t1.display( );
    
    return 0;    
}

三、重载流插入运算符和

1、在C++中,cin属于istream类的对象,cout属于ostream类的对象;
2、>>和<<是移位运算符,进行了重载;

(一)<<运算符重载函数的形式

ostream &operator<<(ostream&, const 自定义类&);

1)参数1:ostream&
2)参数2:要输出的自定义类
3)函数类型:ostream&
注:
由于有两个当前类外的入参,因此只能不能使用成员函数形式,只能友元或普通函数。返回类型要加&.

例6 重载流插入运算符
#include <iostream>
#include <cmath>
using namespace std;

#include <iostream>
using namespace std;
class Complex
{
public:
    Complex( ){real=0;imag=0;}                              //构造函数
    Complex(double r,double i){real=r;imag=i;}              //重载构造函数带参
    Complex operator + (Complex &c2);                       //+运算符重载函数
    friend ostream& operator << (ostream&, const Complex&); //<<输出流运算符重载函数,返回类型加&
private:
    double real;
    double imag;
};

Complex Complex::operator + (Complex &c2)
{
    return Complex(real+c2.real,imag+c2.imag);
}

ostream& operator << (ostream& output,const Complex& c)     //
{
    output<<"("<<c.real<<"+"<<c.imag<<"i)";
    return output;
}


int main( )
{
    Complex c1(2,4),c2(6,10),c3;
    cout<<c1<<c2<<endl;               //等同于operator<<(operator<<(cout,c1),c2),运算符重载嵌套!
    c3=c1+c2;
    cout<<c1<<'+'<<c2<<'='<<c3<<endl;
    return 0;
}


http://www.kler.cn/a/458464.html

相关文章:

  • Springboot3.x整合swagger3
  • perl:多线程 简单示例
  • 三大行业案例:AI大模型+Agent实践全景
  • 20241218-信息安全理论与技术复习题
  • 前端安全措施:接口签名、RSA加密、反调试、反反调试、CAPTCHA验证
  • Day60 图论part10
  • 学习记录2024/12/25;用C语言实现通讯录功能
  • 将 SOLID 原则应用于 Spring Boot 应用程序
  • .Net Core配置系统
  • 力扣251题详解:展开二维向量的多种解法与模拟面试
  • 无法验证服务器身份是什么意思?
  • 关于harmonyOS Next中状态管理的学习
  • 探秘 Neat 公司的自动测试架构:如何高效创造与价值保持
  • ThinkPHP 8开发环境安装
  • 【IC验证】verilog及systemverilog特殊特性的分析
  • uniapp-vue3(下)
  • Direct Preference Optimization: Your Language Model is Secretly a Reward Model
  • MIT实验笔记冲刺3:页表操作(理论部分)
  • 解锁ChatGPT潜力:打造属于你的AI助手
  • 基于Springboot的高校办公室行政事务管理系统【附源码】
  • Linux 的信号机制
  • 使用C#生成一张1G大小的空白图片
  • Django REST framework 源码剖析-路由详解(Routers)
  • Docker 开启远程端口访问2375
  • Java的责任链模式在项目中的使用
  • 如何优化求职简历从模板选择到面试准备