C++运算符重载实例

一、重载双目运算符

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

注:

1)比较规则:调用int strcmp(const char *str1, const char *str2)函数,按照ASCII码表从首字母开始比较str1和str2的值。

2)因为算数运算符需要两个对象(左、右各一个操作数),因此只能用友元函数形式。

3)运算符重载可以嵌套使用。

cpp 复制代码
#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 重载复合赋值运算符+=
cpp 复制代码
#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 重载~取反运算符,实现分数类对象的倒数
cpp 复制代码
#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 重载前置++运算符,实现时钟加一秒
cpp 复制代码
#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 重载后置++运算符(特殊)

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

cpp 复制代码
Time operator++( );    //前置++
Time operator++(int);  //后置++

完整代码:

cpp 复制代码
#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、>>和<<是移位运算符,进行了重载;

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

cpp 复制代码
ostream &operator<<(ostream&, const 自定义类&);

1)参数1:ostream&

2)参数2:要输出的自定义类

3)函数类型:ostream&

注:

由于有两个当前类外的入参,因此只能不能使用成员函数形式,只能友元或普通函数。返回类型要加&.

例6 重载流插入运算符
cpp 复制代码
#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;
}
相关推荐
新手小袁_J7 分钟前
java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigur
java·开发语言·spring·spring cloud·bootstrap·maven·mybatis
墨鸦_Cormorant7 分钟前
Java 创建图形用户界面(GUI)组件详解之下拉式菜单(JMenu、JMenuItem)、弹出式菜单(JPopupMenu)等
java·开发语言·gui
cccccc语言我来了8 分钟前
c++-----------------多态
java·开发语言·c++
南鸢1.010 分钟前
11张思维导图带你快速学习java
java·开发语言
sunny-ll12 分钟前
【C++】explicit关键字详解(explicit关键字是什么? 为什么需要explicit关键字? 如何使用explicit 关键字)
c语言·开发语言·c++·算法·面试
泯泷13 分钟前
JS代码混淆器:JavaScript obfuscator 让你的代码看起来让人痛苦
开发语言·javascript·ecmascript
轩源源16 分钟前
C++草原三剑客之一:继承
开发语言·数据结构·c++·算法·青少年编程·继承·组合
未知陨落22 分钟前
leetcode题目(1)
c++·leetcode
每天写点bug2 小时前
【go每日一题】 责任链模式的实现
开发语言·golang·责任链模式
半盏茶香3 小时前
C语言勘破之路-最终篇 —— 预处理(下)
c语言·开发语言·c++·算法