《21天学通C++》(第十二章)运算符类型与运算符重载

1.为什么要重载运算符?

通过重载运算符,可以将复杂的操作封装成简单的运算符形式,简化代码,提高可读性下面举一个简单的例子

计算两个点的坐标之和。

1.不重载运算符

#include <iostream>  
using namespace std; 

class Point { 
public:
    int x, y;  // Point类的成员变量,表示点的x和y坐标

    // 构造函数,初始化x和y坐标
    Point(int x, int y) : x(x), y(y) {}

    // 成员函数,用于计算两个点的坐标之和并返回新的Point对象
    Point add(const Point& other) const {
        return Point(x + other.x, y + other.y);  
        // 返回一个新Point,其坐标为当前对象和other对象坐标的和
    }
};

int main() {
    Point p1(1, 2);  // 创建一个Point对象p1,坐标为(1, 2)
    Point p2(3, 4);  // 创建另一个Point对象p2,坐标为(3, 4)

    // 使用成员函数add来计算两个点的坐标之和,并将结果赋值给p3
    Point p3 = p1.add(p2);

    // 使用cout输出p3的坐标,格式为"(x, y)"
    cout << "The sum of p1 and p2 is: (" << p3.x << ", " << p3.y << ")" << endl;
    system("pause");
    return 0; 
}

2.使用重载运算符

#include <iostream> 
using namespace std; 

class Point { 
public:
    int x, y; 

    // 构造函数,用于初始化点的x和y坐标
    Point(int x, int y) : x(x), y(y) {}

    // 重载 "+" 运算符,使其能够用于Point类的对象
    // 这个函数接受一个Point对象作为参数,并返回一个新的Point对象
    // 新对象的坐标是原两个Point对象坐标的和
    Point operator+(const Point& other) const {
        return Point(x + other.x, y + other.y); 
    // 返回一个新的Point对象,其坐标为当前对象和other对象坐标的和
    }
};

int main() {
    Point p1(1, 2);  // 创建一个Point对象p1,其坐标为(1, 2)
    Point p2(3, 4);  // 创建另一个Point对象p2,其坐标为(3, 4)

    // 使用重载的 "+" 运算符来计算两个Point对象的坐标之和
    // 这行代码等价于调用 p1.add(p2),但由于运算符重载,我们可以直接使用 + 号
    Point p3 = p1 + p2;
    
    cout << "The sum of p1 and p2 is: (" << p3.x << ", " << p3.y << ")" << endl;
    system("pause");
    return 0; 
}

重载运算符后可以使用+来进行坐标点的运算,代码更加简洁,可读性更高

2.单目运算符

即只能对一个操作数进行操作

单目运算符的类型
在这里插入图片描述
单目递增与单目递减运算符
一个可以对日期进行递增和递减的操作,代码如下:

#include <iostream>
using namespace std;

class Date {
private:
    int day;
    int month;
    int year;

    // 简化版的日期合法性检查
    void checkDate() {
        // 如果是2月28日,增加到3月1日
        if (month == 2 && day == 29) {
            day = 1;
            month = 3;
        }
        // 如果月份超过12,增加年份
        if (month > 12) {
            month = 1;
            year++;
        }
    }

public:
    // 构造函数
    Date(int d, int m, int y) : day(d), month(m), year(y) {
        checkDate();
    }

    // 单目递增运算符重载
    Date& operator++() {
        day++;
        checkDate();
        return *this;
    }

    // 成员函数用于输出日期
    void diplayDate() const {
        cout << day << "/" << month << "/" << year;
    }
};

int main() {
    Date today(28, 2, 2024); // 今天是2024年2月28日

    today.diplayDate(); // 使用成员函数输出日期
    cout << endl; // 输出换行
    ++today;       // 使用重载后的递增运算符
    today.diplayDate(); // 使用成员函数输出日期
    cout << endl; // 输出换行
    system("pause");
    return 0;
}

PS: 还可以使用后缀运算符,但如果只是想执行递增递减运算,应当选择前缀运算符。
因为在后缀运算符中,首先会复制当前对象,再对当前对象执行递增递减运算,最后返回复制对象,会多一步临时拷贝的步骤,且这个创建的临时拷贝也不会被使用

3.转换运算符

示例代码如下:

#include <iostream>
#include <sstream>
#include <string>
using namespace std;

class Date {
private:
    int day;
    int month;
    int year;
    string dateInString; // 用于存储格式化后的日期字符串

    // 简化版的日期合法性检查
    void checkDate() {
        // 如果是2月28日,增加到3月1日(这里不考虑闰年)
        if (month == 2 && day == 29) {
            day = 1;
            month = 3;
        }
        // 如果月份超过12,增加年份
        if (month > 12) {
            month = 1;
            year++;
        }
    }

public:
    // 构造函数,初始化日期并检查合法性
    Date(int d, int m, int y) : day(d), month(m), year(y) {
        checkDate();
    }

    // 单目递增运算符重载,将日期递增一天
    Date& operator++() {
        day++;
        checkDate();
        return *this;
    }

    // 类型转换运算符,将Date对象转换为const char*类型
    // 这样,Date对象可以直接被ostream类使用,如cout
    operator const char* (){
        // 使用ostringstream将日期转换为字符串
        ostringstream oss;
        oss << month << "/" << day << "/" << year;
        // 将转换后的字符串存储在dateInString中
        dateInString = oss.str();
        // 返回字符串的C风格字符数组(const char*)
        return dateInString.c_str();
    }
};

int main() {
    Date today(28, 2, 2024); 
    // 使用类型转换运算符将Date对象转换为const char*,并使用cout输出
    cout << "Tomorrow's date: " << today << endl;
   
    system("pause");
    return 0;
}

通过类型转化后,可以使用cout直接输出

4.双目运算符

可以对两个操作数进行操作的运算符
在这里插入图片描述

5.函数运算符operator()

函数运算符允许类的实例表现得就函数一样,可以接受参数返回结果

#include <iostream>
#include <string>

class SimpleFunc {
public:
    // 重载()运算符,使其可以像函数一样被调用
    int operator()(int a, int b) {
        return a + b; // 这里我们简单地返回两个数的和
    }
};

int main() {
    SimpleFunc func; // 创建SimpleFunc的实例

    // 使用SimpleFunc实例来计算两个数的和
    int result = func(3, 5); // 调用func对象,传入3和5作为参数

    // 输出结果
    std::cout << "The sum of 3 and 5 is: " << result << std::endl;
    system("pause");
    return 0;
}

6.移动构造函数和移动赋值运算符

移动构造函数和移动赋值运算符是性能优化功能,用于高性能编程,属于C++11标准的一部分,旨在避免复制不必要的临时值

移动构造函数: 移动构造函数是一个接受一个同类型对象的右值引用作为参数的构造函数。它的主要目的是在对象的构造过程中,将资源从另一个对象“移动”过来,而不是进行复制

class MyClass {
public:
    MyClass(MyClass&& other) noexcept {//声明方法
        // 移动资源
    }
};

移动赋值运算符: 移动赋值运算符是一个接受一个同类型对象的右值引用作为参数的赋值运算符。它允许一个对象通过接管另一个对象的资源来改变其状态,而不是通过复制

class MyClass {
public:
    MyClass& operator=(MyClass&& other) noexcept {//声明方法
        // 移动资源并赋值
        return *this;
    }
};

7.不能重载的运算符

在这里插入图片描述

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青石横刀策马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值