当前位置: 首页 > article >正文

【C++指南】运算符重载详解

引言

C++ 提供了运算符重载这一特性,允许程序员为自定义类型(如类和结构体)定义运算符的行为

通过运算符重载,可以使自定义类型对象像内置类型一样使用运算符,从而提高代码的可读性和易用性。

本文将详细介绍 C++ 中运算符重载的概念、语法、规则、注意事项以及实际应用。

 

目录

引言

 🍃运算符重载的概念

🍃运算符重载的语法

🍃可重载的运算符

🍃运算符重载的规则

🍃运算符重载的实现

🍃注意事项

🍃实际应用

示例代码

运算符重载的应用项目:日期类实现

结语


 🍃运算符重载的概念

运算符重载是指为类(或结构体)的特定运算符提供自定义实现,使其能够作用于类的对象。重载的运算符可以保持其原有的语义,也可以定义新的语义。

C++规 定类类型对象使⽤运算符时,必须转换成调⽤对应运算符重载,若没有对应的运算符重载,则会编译报错。

🍃运算符重载的语法

  • 运算符重载通过成员函数或友元函数来实现。
  • 运算符重载是具有特殊名字的函数,他的名字是由operator和后⾯要定义的运算符共同构成。
  • 和其他 函数⼀样,它也具有其返回类型和参数列表以及函数体。
  • 如果⼀个重载运算符函数是成员函数,则它的第⼀个运算对象默认传给隐式的this指针,因此运算 符重载作为成员函数时,参数比运算对象少⼀个 

  • 成员函数形式
class MyClass {  
public:  
    MyClass operator+(const MyClass& other) const; // 重载加法运算符  
    // ... 其他成员 ...  
};
  • 友元函数形式
class MyClass {  
public:  
    friend MyClass operator+(const MyClass& lhs, const MyClass& rhs); // 声明友元函数  
    // ... 其他成员 ...  
};  
  
// 类外部定义友元函数  
MyClass operator+(const MyClass& lhs, const MyClass& rhs) {  
    // 实现加法运算  
}

🍃可重载的运算符

C++ 允许重载几乎所有的运算符,但有几个运算符不能重载:  .  .*    ::    ?:   sizeof 和 typeid。这些运算符与对象的成员访问、类型信息获取等底层操作紧密相关,因此不允许重载。

🍃运算符重载的规则

  • 不能改变运算符的优先级和结合性:重载的运算符仍然保持其原有的优先级和结合性。
  • 不能改变运算符的操作数个数:例如,不能将一元运算符重载为二元运算符,反之亦然。
  • 重载的运算符不能是新的类型:重载的运算符必须是 C++ 中已定义的运算符。
  • 成员运算符函数不能有默认参数:重载的运算符函数不能有默认参数。

🍃运算符重载的实现

  • 成员函数形式:当运算符重载为成员函数时,左侧操作数必须是该类的一个对象(或引用),而右侧操作数可以是任意类型(包括内置类型和该类类型)。
  • 友元函数形式:当运算符重载为友元函数时,两个操作数可以是任意类型(包括内置类型和该类类型),这提供了更大的灵活性。

🍃注意事项

  • 避免不必要的重载:只有当运算符的默认行为不适用于自定义类型时,才考虑重载。
  • 保持语义一致性:重载的运算符应尽可能保持其原有的语义,以避免混淆。
  • 注意异常安全性:在重载运算符时,要考虑到异常安全性,确保在异常发生时不会泄露资源或破坏对象状态。
  • 实用性:⼀个类需要重载哪些运算符,是看哪些运算符重载后有意义
  • 前置++与后置++:重载++运算符时,有前置++和后置++,运算符重载函数名都是operator++,无法很好的区分。 C++规定,后置++重载时,增加⼀个int形参,跟前置++构成函数重载,方便区分
  • 重载>>和<<:需要重载为全局函数,因为重载为成员函数,this指针默认抢占了第⼀个形参位 置,第⼀个形参位置是左侧运算对象,调⽤时就变成了对象<<cout,不符合语法和习惯。重载为全局函数把ostream/istream放到第⼀个形参位置就可以了,第⼆个形参位置当类类型对象

🍃实际应用

运算符重载在 C++ 中有着广泛的应用,例如:

  • 复数类:可以重载加法、减法、乘法和除法等运算符,使复数对象能够像内置类型一样进行算术运算。
  • 点类:可以重载加法运算符来表示点的平移,重载减法运算符来表示点的距离计算等。
  • 字符串类:可以重载加法运算符来表示字符串的连接,重载比较运算符来表示字符串的大小比较等。

示例代码

以下是一个简单的复数类示例,展示了如何重载加法、减法和乘法运算符:

#include <iostream>  
  
class Complex {  
private:  
    double real;  
    double imag;  
  
public:  
    // 构造函数  
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}  
  
    // 重载加法运算符  
    Complex operator+(const Complex& other) const {  
        return Complex(real + other.real, imag + other.imag);  
    }  
  
    // 重载减法运算符  
    Complex operator-(const Complex& other) const {  
        return Complex(real - other.real, imag - other.imag);  
    }  
  
    // 重载乘法运算符  
    Complex operator*(const Complex& other) const {  
        return Complex(real * other.real - imag * other.imag, real * other.imag + imag * other.real);  
    }  
  
    // 重载输出运算符  
    friend std::ostream& operator<<(std::ostream& os, const Complex& c) {  
        os << c.real << " + " << c.imag << "i";  
        return os;  
    }  
};  
  
int main() {  
    Complex c1(1, 2);  
    Complex c2(3, 4);  
  
    Complex c3 = c1 + c2;  
    Complex c4 = c1 - c2;  
    Complex c5 = c1 * c2;  
  
    std::cout << "c1: " << c1 << std::endl;  
    std::cout << "c2: " << c2 << std::endl;  
    std::cout << "c1 + c2: " << c3 << std::endl;  
    std::cout << "c1 - c2: " << c4 << std::endl;  
    std::cout << "c1 * c2: " << c5 << std::endl;  
  
    return 0;  
}

在这个示例中,我们定义了一个 Complex 类来表示复数,并重载了加法、减法和乘法运算符,以及输出运算符。这样,我们就可以像使用内置类型一样使用 Complex 对象进行算术运算和输出。

运算符重载的应用项目:日期类实现

详细内容参考文章,点击下方链接:

【C++指南】类和对象入门实践:日期类实现-CSDN博客

结语

运算符重载是 C++ 中的一个强大特性,它允许程序员为自定义类型定义运算符的行为。通过合理地使用运算符重载,可以使代码更加简洁、易读和高效。然而,在重载运算符时,需要遵循一定的规则和注意事项,以确保代码的正确性和安全性。

 


http://www.kler.cn/news/363625.html

相关文章:

  • MoeCTF 2024 ---Misc方向WP
  • 【摄像头产品介绍性能特点优点】
  • 数字+文旅:AI虚拟数字人如何焕发传统文旅景区新活力?
  • SpringCloud学习记录|day6
  • 软件设计模式------抽象工厂模式
  • Android 设置控件为圆形
  • 【JAVA毕设】基于JAVA的酒店管理系统
  • Flink SQL+Hudi数据入湖与分析实践
  • Scala的reduce
  • 昆虫种类识别数据集昆虫物种分类数据集YOLO格式VOC格式 目标检测 机器视觉数据集
  • 牛客周赛64(C++实现)
  • 你真的了解Canvas吗--解密十二【ZRender篇】
  • 【AI创新】优化ChatGPT提示词Prompt设计:释放AI的无限潜能
  • 使用AITemplate和AMD GPU的高效图像生成:结合Stable Diffusion模型
  • 数据结构(8.2_1)——插入排序
  • KOC营销崛起:怎样统计每个达人的App推广效果?
  • vscode连接keil-5 开发STM32 程序
  • Windows下搭建VUE开发环境
  • 一文搞定二叉树
  • 智慧楼宇平台,构筑未来智慧城市的基石
  • Vue入门示例
  • 【Docker】【Mini_Postgresql_Image】打造Mini版 Postgresql Docker镜像
  • 关于MyBatis的一些面试题
  • node16 linux安装node环境 node.js16
  • 【前端Vue学习笔记】组件注册方式 组件传递数据 组件事件 透传 插槽slot 组件生命周期 动态组件 异步组件 依赖注入 Vue应用
  • 用PHP爬虫API,轻松获取taobao商品SKU信息