第四章 运算符重载

学习目的

  1. 掌握运算符函数的定义;
  2. 掌握+、-、++、+=等常用运算符的重载;
  3. 了解<<运算符、前置和后置++运算符的使用;
  4. 掌握C++11中移动赋值运算符等语言扩展机制。

实习任务

  • 实习任务一

#include <iostream>
#include <cmath>
using namespace std;
class Complex{
public:
    Complex();
    Complex(int n);
    Complex(int n, int d);
    Complex(const Complex& c);
    ~Complex();
    void setValue(int n, int d);
    double getReal()const;
    double getImage()const;
    double getDistance()const;
    void output()const;
    Complex operator+(const Complex& f)const;
    Complex operator*(const Complex& f)const;
    Complex & operator+=(const Complex & f);
    Complex & operator*=(const Complex & f);
    Complex &operator++(void);
    Complex  operator++(int);
    Complex & operator-=(const Complex & f);
    friend Complex operator-(const Complex & f1, const Complex & f2)const;
    friend Complex operator-(const Complex& f)const;
    friend ostream & operator<<(ostream& out, const Complex& f);
private:
    double real;
    double image;
};
Complex::Complex(){
    real = 0;
    image = 0;
}
Complex::Complex(int n){
    real = n;
    image = 0;
}
Complex::Complex(int n, int d){
    real = n;
    image = d;
}
Complex::Complex(const Complex&c){
    real = c.getReal();
    image = c.getImage();
}
Complex::~Complex(){
    // cout<<"destructed!"<<endl;
}
void Complex::setValue(int n, int d){
    real = n;
    image = d;
}
double Complex::getReal()const{
    return real;
}
double Complex::getImage()const{
    return image;
}
double Complex::getDistance()const{
    return sqrt(real*real+image*image);
}
void Complex::output()const{
    if(image==0){
        cout<<real;
    }
    else if(real == 0 && image!=0){
        if(image == 1)
            cout<<'i';
        else
            cout<<image<<'i';
    }
    else if(image > 0){
        if(image == 1)
            cout<<real<<'+'<<'i';
        else
            cout<<real<<'+'<<image<<'i';
    }
    else{
        cout<<real<<image<<'i';
    }
    cout<<endl;
}
Complex Complex::operator+(const Complex& f)const{
    Complex temp(real+f.getReal(), image+f.getImage());
    return temp;
}
Complex Complex::operator*(const Complex& f)const{
    Complex temp(real*f.getReal()-image*f.getImage(),real*f.getImage()+image*f.getReal());
    return temp;
}
Complex & Complex::operator+=(const Complex & f){
    real+=f.getReal();
    image+=f.getImage();
    return *this;
    //"this" is important!
}
Complex & Complex::operator*=(const Complex & f){
    int r = real*f.getReal()-image*f.getImage();
    int i = real*f.getImage()+image*f.getReal();
    real = r;
    image = i;
    return *this;
}

Complex & Complex::operator++(void){
    ++real;
    return *this;
}
Complex Complex::operator++(int){
    real++;
    return Complex(real, image);
}
Complex & Complex::operator-=(const Complex & f){
    real-=f.getReal();
    image-=f.getImage();
    return *this;
}
//友元函数实现减法
Complex operator-(const Complex & f1, const Complex & f2){
    return Complex(f1.getReal()-f2.getReal(), f1.getImage()-f2.getImage());
}
//友元函数实现负数
Complex operator-(const Complex& f){
    return Complex(-f.real, -f.image);
}
ostream& operator<<(ostream& out, const Complex& f){
    if(f.image==0){
        out<<f.real;
    }
    else if(f.real == 0 && f.image!=0){
        if(f.image == 1)
            out<<'i';
        else
            out<<f.image<<'i';
    }
    else if(f.image > 0){
        if(f.image == 1)
            out<<f.real<<'+'<<'i';
        else
            out<<f.real<<'+'<<f.image<<'i';
    }
    else{
        out<<f.real<<f.image<<'i';
    }
    return out;
}
int main(){
    Complex a(2,3), b(1,4), c(9,1), d(0,0);
    c++.output();
    cout<<c<<endl<<b<<endl;
    return 0;
}
运行结果:
10+i
10+i
1+4i
[Finished in 0.3s]
  • 实习任务二

#include <iostream>
#include <cmath>
using namespace std;
class Time{
public:
    Time(){
        hour = 0;
        minute = 0;
        normalizeTime();
    }
    Time(int h, int m){
        hour = h;
        minute = m;
        normalizeTime();
    }
    Time(int minutes){
        hour = (minutes/60)%24;
        minute = minutes%60;
        normalizeTime();
    }
    void setTime(int h, int m){
        hour = h;
        minute = m;
        normalizeTime();
    }
    friend ostream& operator<<(ostream& out,const Time& t);
    void output()const{       
        cout<<hour<<':'<<minute<<endl;
    }
    int getHour()const{
        return hour;
    }
    int getMinute()const{
        return minute;
    }
    int getTotalMinutes()const{
        return hour*60 + minute;
    }
    Time getTimeSpan(const Time &t)const{
        Time x;
        int dis = abs(getTotalMinutes() - t.getTotalMinutes());
        x.setTime((dis/60)%24, dis%60);
        return x;
    }
    Time operator-(const Time& newTime){
        int dis = abs(getTotalMinutes() - newTime.getTotalMinutes());
        return Time((dis/60)%24, dis%60);
    }
    friend ostream& operator<<(ostream& out, const Time& t){
        out<<t.hour<<':'<<t.minute<<endl;
        return out;
    }
private:
    int hour;
    int minute;
    void normalizeTime(){
        hour = ((60*hour + minute)/60)%24;
        minute = minute%60;
    }
};
int main(){
    Time t1(12, 75);
    t1.output();
    cout<<t1;
    t1.setTime(8, 65);
    t1.output();
    Time t2(12, 13);
    t1.getTimeSpan(t2).output();
    cout<<"t1 Hour:"<<t1.getHour()<<endl;
    cout<<"t1 Minute:"<<t1.getMinute()<<endl;
    cout<<"t1 getTotalMinutes:"<<t1.getTotalMinutes()<<endl;

    return 0;
}
运行结果:
13:15
13:15
9:5
3:8
t1 Hour:9
t1 Minute:5
t1 getTotalMinutes:545
[Finished in 0.3s]
#include <iostream>
#include <cmath>
using namespace std;
#include <iostream>
#include <cmath>
using namespace std;
class Time{
public:
    Time(){
        hour = 0;
        minute = 0;
        normalizeTime();
    }
    Time(int h, int m){
        hour = h;
        minute = m;
        normalizeTime();
    }
    Time(int minutes){
        hour = (minutes/60)%24;
        minute = minutes%60;
        normalizeTime();
    }
    void setTime(int h, int m){
        hour = h;
        minute = m;
        normalizeTime();
    }
    friend ostream& operator<<(ostream& out,const Time& t);
    void output()const{       
        cout<<hour<<':'<<minute<<endl;
    }
    int getHour()const{
        return hour;
    }
    int getMinute()const{
        return minute;
    }
    int getTotalMinutes()const{
        return hour*60 + minute;
    }
    // Time getTimeSpan(const Time &t)const{
    //     Time x;
    //     int dis = abs(getTotalMinutes() - t.getTotalMinutes());
    //     x.setTime((dis/60)%24, dis%60);
    //     return x;
    // }
    Time operator-(const Time& newTime)const{
        int dis = abs(getTotalMinutes() - newTime.getTotalMinutes());
        return Time((dis/60)%24, dis%60);
    }
    friend ostream& operator<<(ostream& out, const Time& t){
        out<<t.hour<<':'<<t.minute<<endl;
        return out;
    }
private:
    int hour;
    int minute;
    void normalizeTime(){
        hour = ((60*hour + minute)/60)%24;
        minute = minute%60;
    }
};
class ParkingCard{
public:
    ParkingCard(double newRate){
        rate = newRate;
    }
    void setRate(double newRate){
        rate = newRate;
    }
    double getRate()const{
        return rate;
    }
    void setParkingTime(const Time &time){
        parkingTime.setTime(time.getHour(), time.getMinute());
    }
    void setLeavingTime(const Time &time){
        leavingTime.setTime(time.getHour(), time.getMinute());
    }
    double getTotalExpenses()const{
        Time x = parkingTime-leavingTime;
        return x.getTotalMinutes()*(rate/60.0);
    }

    void output()const{
        cout<<"Your parking time: ";
        parkingTime.output();
        cout<<"Our parking rate: ";
        cout<<rate<<endl;
        cout<<"Your total expenses: ";
        cout<<getTotalExpenses()<<endl<<endl;
    }
private:
    double rate;
    Time parkingTime;
    Time leavingTime;
};
int main(){
    ParkingCard card(5);
    card.setParkingTime(Time(9,20));
    card.setLeavingTime(Time(11,35));
    cout<<"Expenses:"<<card.getTotalExpenses()<<endl;
    cout<<"Detailed info:\n";
    card.output();

    return 0;
}
运行结果:
Expenses:11.25
Detailed info:
Your parking time: 9:20
Our parking rate: 5
Your total expenses: 11.25

[Finished in 0.3s]
  • 实习任务三 最终版

#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
class MyString{
public:
    MyString(const char *s){
        str=new char[strlen(s)+1];
        strcpy(str,s);
    }
    MyString(const string & st){
        str=new char[st.size()+1];
        strcpy(str, st.c_str());
    }
    MyString(){
        str=nullptr;
    }
    
    MyString(const MyString& s){
        str = new char[s.size()+1];
        strcpy(str,s.str);
    }
    MyString(MyString&& s){
        str = s.str;
        s.str = nullptr;
    }
    
    ~MyString();
    MyString& operator=(const MyString& s);
    MyString& operator=(MyString&& s);
    
    int size()const;//check
    
    friend MyString operator+(const MyString& s1, const MyString& s2);
    
    const char& operator[](int index)const;
        
    char& operator[](int index);
    
    friend ostream& operator<<(ostream& out,const MyString& s);//check
private:
    char *str;
};
    MyString::~MyString(){
    delete[] str;
}
MyString operator+(const MyString& s1, const MyString& s2){
    MyString stri;
    stri.str = new char[s1.size()+s2.size()+2];
    strcpy(stri.str,s1.str);
    stri.str[s1.size()] = ' ';
    stri.str[s1.size()+1] = '\0';
    strcat(stri.str,s2.str);
    return stri;
}

MyString& MyString::operator=(const MyString& s){
    if(&s==this){
        return*this;
    }
    delete[] str;
    str = new char[size()+s.size()+1];
    return *this;
}
MyString& MyString::operator=(MyString&& s){
    str  = s.str;
    s.str = nullptr;
    return *this;
}
int MyString::size()const{
    return (int)strlen(str);
}
const char& MyString::operator[](int index)const{
    return str[index];
}

char& MyString::operator[](int index){
    return str[index];
}

ostream& operator<<(ostream& out,const MyString& s){
    out<<s.str;
    return out;
}
int main(){
    MyString s("Hello");
    cout<<s<<endl;
    MyString s2="World"+s+"world again"+s;
    cout<<"s2: "<<s2<<endl;
    cout<<"Index 5:"<<s2[4]<<endl;
    MyString s3(move(s2));//移动拷贝构造,删除了s2,再次cout<<s2会报错,
    cout<<s3<<endl;
    return 0;
}
运行结果:
Hello
s2: World Hello world again Hello
Index 5:d
World Hello world again Hello
Program ended with exit code: 0

课后练习

#include <iostream>
#include <vector>
using namespace std;
class Test{
private:
    int x;
public:
    Test operator++(int){
        Test temp(*this);
        x++;
        cout<<"t++";
        return temp;
    }
    Test(int xx=0):x(xx){}
    Test& operator++(){
        x++;
        cout<<"++t";
        return *this;
    }
    int getValue()const{
        return x;
    }
};
int main(){
    Test t;
    cout<<t.getValue()<<endl;
    cout<<(t++).getValue()<<endl;
    cout<<(++t).getValue()<<endl;
    return 0;
}
运行结果:
0
t++0
++t2
[Finished in 0.3s]
#include <iostream>
using namespace std;
class Matrix{
    double * elem;
    int row, col;
public:
    Matrix(int r, int c){
        row = r;
        col = c;
        elem = new double[row*col];
    }
    double & operator()(int x, int y){
        return elem[col*(x-1)+y-1];
    }
    double &operator()(int x, int y)const{
        return elem[col*(x-1)+y-1];
    }
    ~Matrix(){delete[] elem;}
};
int main()
{
    Matrix m(5,8);
    int i;
    for(i = 0;i<6; i++)
        m(i,1) = i+5;
    for(i = 1; i < 6; i++)
        cout<<m(i,1)<<",";
    cout<<endl;
    return 0;
}
运行结果:
6,7,8,9,10,
[Finished in 0.4s]
#include <iostream>
using namespace std;
class Array{
private:
    int *pdata;
    int size;
public:
    Array():size(0){
        pdata = nullptr;
    }
    Array(int s):size(s){
        pdata = new int[size];
    }
    ~Array(){
        delete[] pdata;
    }
    Array(const Array& a):size(a.size){
        pdata = new int[size];
        for(int i = 0; i < size; ++i)
            pdata[i] = a[i];
    }//copy array
    Array(Array&& a):size(a.size){
        pdata = a.pdata;
        a.size = 0;
        a.pdata = nullptr;
    }
    Array& operator=(const Array& a){
        if(this==&a)//如果是a = a,或者&b = a; b =a ,那么就返回b
            return *this;
        size = a.size;
        pdata = new int[size];
        for(int i=0; i<size; ++i)
            pdata[i] = a[i];
        return *this;
    }
    Array& operator=(Array&& a){
        if(this==&a)
            return * this;
        size = a.size;
        pdata = a.pdata;
        a.size = 0;
        a.pdata = nullptr;
        return * this;
    }
    const int& operator[](int index)const{
        return pdata[index];
    }
    int& operator[](int index){
        return pdata[index];
    }
    int length()const{
        return size;
    }

};

int main()
{
    Array a1(3);
    for(int i=0;i<3;i++)
        a1[i] = i;
    cout<<"length of a1:"<<a1.length()<<endl;
    Array a2(a1);
    cout<<"length of a1:"<<a1.length()<<endl;
    cout<<"length of a2:"<<a2.length()<<endl;
    Array a3(move(a1));
    cout<<"length of a1:"<<a1.length()<<endl;
    cout<<"length of a3:"<<a3.length()<<endl;
    return 0;
}
运行结果:
length of a1:3
length of a1:3
length of a2:3
length of a1:3
length of a3:3
[Finished in 0.3s]
#include <iostream> 
#include <vector> 
using namespace std; 
class Fraction{ 
private:
    int num,den; 
public:
    explicit Fraction(int n=0,int d=1):num(n),den(d){} 
    explicit operator double()const {
            return 1.0*num/den; 
    } 
    //?
    Fraction operator+(const Fraction& f)const{
        return Fraction(num*f.den+den*f.num,den*f.den); 
    }
    void output()const{
        cout<<num<<"/"<<den<<endl;
    } 
};
int main(){
    Fraction f1(1,3);
    f1.output();
    Fraction f2=f1+static_cast<Fraction>(1); 
    f2.output();
    cout<<1+static_cast<double>(f1)<<endl; //?
    return 0;
}
运行结果:
1/3
4/3
1.33333
[Finished in 0.4s]
#include <iostream>
#include <vector>
using namespace std;
class Array1D{
private:
    vector<int>vec;
public:
    void push_back(int data){
        vec.push_back(data);
    }
    int& operator[](int index){
        return vec[index];
    }
    const int& operator[](int index)const{
        return vec[index];
    }
};
class Array2D{
private:
    vector<Array1D>vec;
public:
    void push_back(const Array1D& a){
        vec.push_back(a);
    }
    Array1D& operator[](int index){
        return vec[index];
    }
    const Array1D& operator[](int index)const{
        return vec[index];
    }

};
int main(){
    Array2D aa;
    for(int i=0;i<3;++i){
        Array1D a;
        for(int j=0;j<4;++j)
            a.push_back(j+i);
        aa.push_back(a);
    }
    for(int i=0;i<3;++i){
        for(int j=0;j<4;++j)
            cout<<aa[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}
运行结果:
0 1 2 3 
1 2 3 4 
2 3 4 5 
[Finished in 0.4s]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,500评论 1 51
  • C++运算符重载-上篇 本章内容:1. 运算符重载的概述2. 重载算术运算符3. 重载按位运算符和二元逻辑运算符4...
    Haley_2013阅读 2,278评论 0 51
  • 注意:本文中代码均使用 Qt 开发编译环境 面向对象的多态性可以分为四类:重载多态、强制多态、包含多态和参数多态,...
    赵者也阅读 1,131评论 0 3
  • 在PM工作中,有一项东西是需要被仔细考虑,那就是用户的习惯。当增加或减少某项功能,改变某项功能等都需要考虑到用...
    FwonProdutions阅读 1,144评论 0 2
  • 既然提到这两所英语世界中历史最悠久的大学,那么我就需要先简单介绍一下。之前每当朋友们问我:“你现在在哪?”当我回答...
    闻听西辞阅读 636评论 0 5