运算符重载整理

第九章有三个重要的东西
一静态多态:运算符重载
二类型转换
三动态多态:虚函数

然后呢,流插入,流输出,自增自减几乎可以说是必考的了

运算符重载的基础知识

img

img
img
img

两种重载方式

  • 重载为成员函数
  • 重载为友元函数

只能用成员函数重载

= [] () ->

自增运算符重载

既可以成员函数重载也可以友元函数

<函数类型> operator ++(); //前缀运算
<函数类型> operator ++(int); //后缀运算
C++约定: 在自增(自减)运算符重载函数中,增加一个int型形参,就是后置自增(自减)运算符函数。

使用前缀运算符的格式:++<对象>;
使用后缀运算符的格式:<对象>++;

ppt上例子

有一个Time类,包含数据成员minute(分)和sec(秒),模拟秒表,每次走一秒,满60秒进一分钟,此时秒又从0开始算。 要求输出分和秒的值。

#include <iostream>
using namespace std;
class Time
{
public:
Time( )
{minute=0; sec=0;}   // 默认构造函数
Time(int m, int s):minute(m),sec(s){ }  // 构造函数重载
Time operator++( );  // 声明运算符重载函数
void display( )
{cout<<minute<<":"<<sec<<endl;}  // 定义输出时间函数
private:
int minute;
int sec;
};
Time Time∷operator++( )   // 定义运算符重载函数
{    if(++sec>=60)
{	 sec -= 60;  // 满60秒进1分钟
++minute;    }
return *this;   // 返回当前对象值
}
int main( )
{    Time time1(34,0);
for (int i=0;i<61;i++)
{    ++time1;
time1.display( );
}
return 0;
}

在上例的基础上增加对后置自增运算符的重载。

#include <iostream>
using namespace std;
class Time
{public:
Time( ){minute=0;sec=0;}
Time(int m,int s):minute(m),sec(s){ }
Time operator++( ); 	// 声明前置自增运算符“++i”重载函数
Time operator++(int);  // 声明后置自增运算符“i++”重载函数
void display( ){cout<<minute<<":"<<sec<<endl;}
private:
int minute;
int sec;
}; 
Time Time∷operator++( ) // 定义前置自增运算符“++”重载函数
{    if(++sec>=60)
{sec-=60;
++minute;}
return *this; // 返回自加后的当前对象
}
Time Time∷operator++(int) // 定义后置自增运算符“++”重载函数
{    Time temp(*this);
sec++;
if(sec>=60)
{sec-=60;
++minute;}
return temp;   // 返回的是自加前的对象
}
Time Time∷operator++( ) // 定义前置自增运算符“++”重载函数
{    if(++sec>=60)
{sec-=60;
++minute;}
return *this; // 返回自加后的当前对象
}
Time Time∷operator++(int) // 定义后置自增运算符“++”重载函数
{    Time temp(*this);
sec++;
if(sec>=60)
{sec-=60;
++minute;}
return temp;   // 返回的是自加前的对象
}
int main( )
{    Time time1(34,59),time2;
cout<<" time1 : ";
time1.display( );
++time1;
cout<<"++time1: ";
time1.display( );
time2=time1++;   // 将自加前的对象的值赋给time2
cout<<"time1++: ";
time1.display( );
cout<<" time2 :";
time2.display( );  // 输出time2对象的值
}

> <重载

给一道ppt上的题

定义一个字符串类String,用来存放不定长的字符串,重载运算符“=”、“<”和“>”和“==”,用于两个字符串的等于、小于和大于的比较运算。

经典习题

时分秒类运算符重载

--实验4
编写一个时间类,实现时间的加、减、读和输出:
//class.h
class Time
{
public:
Time(){}
void SetTime(int,int,int);
void Display();
Time operator + (Time &a);
Time operator - (Time &a);
private:
int hour,minute,second;
};
另外,在完成上述功能后,根据上述定义:重载 >> 和 << 实现直接输入和输出对象
输入说明:第一行输入第一个时间的时、分、秒,中间用一个空格分隔
第二行输入第二个时间的时、分、秒,中间用一个空格分隔
输出说明:第一行以:分隔时分秒的形式输出两个时间的和
第二行以:分隔时分秒的形式输出两个时间的差
输入样例:6 3 2
5 2 1
输出样例:11:05:03
01:01:01

#include <iostream>
#include <iomanip>

using namespace std;

class Time {
public:
    Time();
    void SetTime(int, int, int);
    void Display();
    Time operator+(Time &a);
    Time operator-(Time &a);

    friend istream& operator>>(istream& in, Time& t);
    friend ostream& operator<<(ostream& out, const Time& t);

private:
    int hour, minute, second;
};

Time::Time() {
    hour = 0;
    minute = 0;
    second = 0;
}

void Time::SetTime(int h, int m, int s) {
    hour = h;
    minute = m;
    second = s;
}

void Time::Display() {
    cout << setfill('0') << setw(2) << hour << ":"
         << setw(2) << minute << ":"
         << setw(2) << second << endl;
}

Time Time::operator+(Time &a) {
    Time res;
    int total_seconds1 = hour * 3600 + minute * 60 + second;
    int total_seconds2 = a.hour * 3600 + a.minute * 60 + a.second;
    int sum_seconds = total_seconds1 + total_seconds2;
    
    res.hour = (sum_seconds / 3600) % 24;
    res.minute = (sum_seconds % 3600) / 60;
    res.second = sum_seconds % 60;
    
    return res;
}

Time Time::operator-(Time &a) {
    Time res;
    int total_seconds1 = hour * 3600 + minute * 60 + second;
    int total_seconds2 = a.hour * 3600 + a.minute * 60 + a.second;
    int diff_seconds = total_seconds1 - total_seconds2;
    
    if (diff_seconds < 0) {
        diff_seconds += 24 * 3600;
    }
    
    res.hour = (diff_seconds / 3600) % 24;
    res.minute = (diff_seconds % 3600) / 60;
    res.second = diff_seconds % 60;
    
    return res;
}

istream& operator>>(istream& in, Time& t) {
    in >> t.hour >> t.minute >> t.second;
    return in;
}

ostream& operator<<(ostream& out, const Time& t) {
    out << setfill('0') << setw(2) << t.hour << ":"
        << setw(2) << t.minute << ":"
        << setw(2) << t.second;
    return out;
}

int main() {
    Time t1, t2;
    
    cin >> t1;
    cin >> t2;
    
    Time sum = t1 + t2;
    Time diff = t1 - t2;
    
    cout << sum << endl;
    cout << diff << endl;
    
    return 0;
}

复数运算符重载

--实验4
生成一个表示复数的类FS。复数的实部sb和虚部xb作为其数据成员。提供成员函数print()显示复数(格式:-3+5i或6-2i),重载“+”、“-”为FS类的成员函数,用来计算两个复数的和、差。
思路导航:
① 定义类,设计构造函数和显示函数print();
② 重载运算符“+”、“-”为类FS的成员函数。
③ 实例化FS类的2个对象,并利用重载的运算符对其进行计算。
另外,在完成上述功能后,根据上述定义:(1)试将上述的运算符重载成员函数改写成友元函数(2)重载 >> 和 << 实现直接输入和输出对象
输入说明:第一行输入第一个复数的实部和虚部,中间用一个空格分隔
第二行输入第二个复数的实部和虚部,中间用一个空格分隔
输出说明:第一行以题目中要求的格式输出两个复数的和
第二行以题目中要求的格式输出两个复数的差
输入样例:9 3
5 2
输出样例:14+5i
4+i

#include <iostream>

using namespace std;

class FS {
public:
    FS();
    FS(int, int);
    void print() const;

    FS operator+(const FS&);
    FS operator-(const FS&);
    friend istream& operator>>(istream&, FS&);
    friend ostream& operator<<(ostream&, const FS&);

private:
    int sb;
    int xb;
};

FS::FS() {
    sb = 0;
    xb = 0;
}

FS::FS(int s, int x) {
    sb = s;
    xb = x;
}

void FS::print() const {
    if (sb == 0 && xb == 0) {
        cout << 0;
    } else if (sb == 0) {
        if (xb == 1) cout << "i";
        else if (xb == -1) cout << "-i";
        else cout << xb << "i";
    } else {
        cout << sb;
        if (xb > 0) {
            if (xb == 1) cout << "+i";
            else cout << "+" << xb << "i";
        } else if (xb < 0) {
            if (xb == -1) cout << "-i";
            else cout << xb << "i";
        }
    }
}

FS FS::operator+(const FS& c) {
    return FS(sb + c.sb, xb + c.xb);
}

FS FS::operator-(const FS& c) {
    return FS(sb - c.sb, xb - c.xb);
}

istream& operator>>(istream& in, FS& c) {
    in >> c.sb >> c.xb;
    return in;
}

ostream& operator<<(ostream& out, const FS& c) {
    if (c.sb == 0 && c.xb == 0) {
        out << 0;
    } else if (c.sb == 0) {
        if (c.xb == 1) out << "i";
        else if (c.xb == -1) out << "-i";
        else out << c.xb << "i";
    } else {
        out << c.sb;
        if (c.xb > 0) {
            if (c.xb == 1) out << "+i";
            else out << "+" << c.xb << "i";
        } else if (c.xb < 0) {
            if (c.xb == -1) out << "-i";
            else out << c.xb << "i";
        }
    }
    return out;
}

int main() {
    FS c1, c2;

    cin >> c1;
    cin >> c2;

    FS sum = c1 + c2;
    FS diff = c1 - c2;

    cout << sum << endl;
    cout << diff << endl;

    return 0;
}


向量运算符重载

--实验4
设计Vector类,通过运算符重载实现向量的加法、减法、点积、叉积、标量乘法、向量乘法、向量除法、向量长度、单位向量、向量夹角、向量旋转、向量反转、向量归一化、向量输出。
输入格式:第一行输入向量的维数n,第二行输入向量的各分量,中间用空格隔开
输出格式:
输入样例:3
1 2 3
输出样例:向量加法:(2,4,6)
向量减法:(-2,0,2)
向量点积:11
向量叉积:-6
标量乘法:(3,6,9)
向量乘法:(6,12,18)
向量除法:(0.5,1,1.5)
向量反转:(-1,-2,-3)
向量输出:(1,2,3)

矩阵运算符重载

五一作业
设计Matrix类,通过运算符重载实现矩阵的和与乘 ;
输入格式
第一行输入A矩阵的行r和列c,后r行输入矩阵的元素
输入B矩阵的行r和列c,后r行输入矩阵的元素
输出格式
第一行输出A+B
如果矩阵A和B可以相加输出矩阵的元素,每个元素所占的宽度为4;否则输出Error
输出AB
如果矩阵A和B可以相加输出矩阵的元素,每个元素所占的宽度为4;否则输出Error
 
输入样例
3 3
1 1 1
1 1 1
1 1 1
3 3
1 2 3
1 5 6
1 2 4
输出样例  
A+B
   2   3   4
   2   6   7
   2   3   5
A
B
   3   9  13
   3   9  13
   3   9  13

#include <iostream>
#include <vector>
#include <iomanip>

using namespace std;

class Matrix {
private:
    int r, c;
    vector<vector<int>> mat;
    bool isValid;

public:
    Matrix() : r(0), c(0), isValid(false) {}

    Matrix(int rows, int cols) : r(rows), c(cols), isValid(true) {
        mat.assign(r, vector<int>(c, 0));
    }

    friend istream& operator>>(istream& in, Matrix& m) {
        in >> m.r >> m.c;
        m.mat.assign(m.r, vector<int>(m.c));
        m.isValid = true;
        for (int i = 0; i < m.r; ++i) {
            for (int j = 0; j < m.c; ++j) {
                in >> m.mat[i][j];
            }
        }
        return in;
    }

    Matrix operator+(const Matrix& b) const {
        if (this->r != b.r || this->c != b.c) {
            return Matrix();
        }
        
        Matrix res(this->r, this->c);
        for (int i = 0; i < this->r; ++i) {
            for (int j = 0; j < this->c; ++j) {
                res.mat[i][j] = this->mat[i][j] + b.mat[i][j];
            }
        }
        return res;
    }

    Matrix operator*(const Matrix& b) const {
        if (this->c != b.r) {
            return Matrix();
        }
        
        Matrix res(this->r, b.c);
        for (int i = 0; i < this->r; ++i) {
            for (int j = 0; j < b.c; ++j) {
                for (int k = 0; k < this->c; ++k) {
                    res.mat[i][j] += this->mat[i][k] * b.mat[k][j];
                }
            }
        }
        return res;
    }

    void print() const {
        if (!isValid) {
            cout << "Error\n";
            return;
        }
        for (int i = 0; i < r; ++i) {
            for (int j = 0; j < c; ++j) {
                cout << setw(4) << mat[i][j];
            }
            cout << "\n";
        }
    }
};

int main() {
    Matrix A, B;
    
    cin >> A;
    cin >> B;
    
    cout << "A+B\n";
    (A + B).print();
    
    cout << "A*B\n";
    (A * B).print();
    
    return 0;
}

人民币运算符重载

1、设计人民币类Money,其数据成员为fen(分)、jiao(角)、yuan(元),如有需要可添加其他数据成员。(本题使用了友元,若用Vc6.0则需更改头文件)

重载这个类的加法、减法运算符,实现人民币的加减并通过 输入输出流的重载直接对该类对象进行输入输出;

输入格式

输入在两行中分别给出3个正整数,以空格隔开

输出格式

若结果为正 :输出几yuan几jiao几fen; 若结果为负:只在前面给出一个负号即可;

输入样例

5 6 9

4 8 3

输出样例

10yuan5jiao2fen

0yuan8jiao6fen

#include <iostream>
#include <cmath> // 必须加上这个头文件,因为要用到 abs()
using namespace std;

class Money {
    friend istream& operator>>(istream&, Money&);
    friend ostream& operator<<(ostream&, const Money&);

public:
    Money(int = 0, int = 0, int = 0);
    
    Money operator+(const Money&) const;
    Money operator-(const Money&) const;

private:
    int yuan, jiao, fen;
};

Money::Money(int y, int j, int f) {
    int total_fen = y * 100 + j * 10 + f;
    yuan = total_fen / 100;
    jiao = (total_fen % 100) / 10;
    fen = total_fen % 10;
}

Money Money::operator+(const Money& m2) const {
    int t1 = yuan * 100 + jiao * 10 + fen;
    int t2 = m2.yuan * 100 + m2.jiao * 10 + m2.fen;
    return Money(0, 0, t1 + t2);
}

Money Money::operator-(const Money& m2) const {
    int t1 = yuan * 100 + jiao * 10 + fen;
    int t2 = m2.yuan * 100 + m2.jiao * 10 + m2.fen;
    return Money(0, 0, t1 - t2);
}

istream& operator>>(istream& in, Money& m) {
    int y, j, f;
    in >> y >> j >> f;
    int total_fen = y * 100 + j * 10 + f;
    m.yuan = total_fen / 100;
    m.jiao = (total_fen % 100) / 10;
    m.fen = total_fen % 10;
    return in;
}

ostream& operator<<(ostream& out, const Money& m) {
    // 只有结果为负,才在最前面输出一个负号
    if (m.yuan < 0 || m.jiao < 0 || m.fen < 0) {
        out << "-";
    }
    // 后面的具体金额必须输出,并且用 abs() 去掉它们自带的负号
    out << abs(m.yuan) << "yuan" << abs(m.jiao) << "jiao" << abs(m.fen) << "fen";
    return out;
}

int main() {
    int y1, j1, f1;
    int y2, j2, f2;
    
    cin >> y1 >> j1 >> f1;
    cin >> y2 >> j2 >> f2;
    
    Money m1(y1, j1, f1), m2(y2, j2, f2);
    
    cout << m1 + m2 << endl;
    cout << m1 - m2 << endl;
    
    return 0;
}


点类运算符重载

定义点类(Point),用以表示几何学点的概念,有属性x、y表示坐标,并重载“-” 单目运算符和“== ” 双目运算符,要求“-”实现对象的成员变量的数值符号取反,而“==”实现判断两个Point类的对象坐标是否相同。

posted @ 2026-05-12 09:55  叶臧  阅读(11)  评论(0)    收藏  举报