第四章 运算符重载

2017-10-25  本文已影响54人  DeepWeaver

学习目的

  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]
上一篇 下一篇

猜你喜欢

热点阅读