运算符重载(Operator Overloading)

2024-03-07 19:28

本文主要是介绍运算符重载(Operator Overloading),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

定义

在C++中,运算符重载(Operator Overloading)是一种允许程序员为自定义数据类型重新定义或重载已有的运算符的功能。通过运算符重载,我们可以使得自定义类型的对象能够像内置类型(如int、float等)一样使用运算符。

运算符重载的规则

  1. 不能改变运算符的优先级和结合性:重载的运算符必须保持其原有的优先级和结合性。
  2. 不能创建新的运算符:我们只能重载C++中已经存在的运算符。
  3. 有些运算符不能被重载:如..*?:sizeoftypeid等运算符不能被重载。
  4. 重载运算符不能改变操作数的个数:重载的运算符必须保持原有的操作数个数。
  5. 重载运算符可以是成员函数或非成员函数:对于非成员函数,需要至少有一个参数是自定义类型;对于成员函数,第一个参数(即this指针)总是隐式的。

示例

下面是一个简单的示例,展示了如何为自定义的复数类重载加法运算符:

#include <iostream>  class Complex {  
public:  double real;  double imag;  Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}  // 重载加法运算符作为成员函数  Complex operator+(const Complex& rhs) const {  return Complex(real + rhs.real, imag + rhs.imag);  }  void print() const {  std::cout << "(" << real << ", " << imag << ")" << std::endl;  }  
};  int main() {  Complex c1(1, 2);  Complex c2(3, 4);  Complex sum = c1 + c2;  // 使用重载的加法运算符  sum.print();           // 输出: (4, 6)  return 0;  
}

编译运行

在这个例子中,我们定义了一个Complex类来表示复数,并为其重载了加法运算符。重载的加法运算符是一个成员函数,它接受一个Complex类型的右操作数(通过const Complex& rhs参数),并返回一个新的Complex对象,该对象的实部和虚部分别是两个操作数对应部分的和。

非成员函数运算符重载示例

有时,将运算符重载为非成员函数可能更为合适,特别是当运算符涉及两个不同类型的对象时。

示例

#include <iostream>  class Complex {  
public:  double real;  double imag;  Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}  // 其他成员函数...  
};  // 重载乘法运算符作为非成员函数  
Complex operator*(const Complex& lhs, const Complex& rhs) {  return Complex(lhs.real * rhs.real - lhs.imag * rhs.imag,  lhs.real * rhs.imag + lhs.imag * rhs.real);  
}  int main() {  Complex c1(1, 2);  Complex c2(3, 4);  Complex product = c1 * c2;  // 使用重载的乘法运算符  // ...  return 0;  
}

在这个例子中,乘法运算符被重载为一个非成员函数,它接受两个Complex类型的参数,并返回一个新的Complex对象,该对象表示两个复数的乘积。注意,非成员函数需要能够访问类的私有成员,因此通常需要将运算符重载函数声明为类的友元函数。然而,在这个例子中,由于我们只需要访问公共成员realimag,因此不需要将运算符重载函数声明为友元。

什么运算符不能重载, 什么运算符能重载

在C++中,不是所有的运算符都可以被重载。以下是关于哪些运算符能重载、哪些不能重载以及为什么的详细解释,并附以例子。

不能重载的运算符

C++中不允许重载的运算符主要包括以下几类:

  1. 点运算符(.)和成员选择运算符(->*:这些运算符用于访问对象的成员,重载它们会破坏语言的基本结构和语义。
  2. 作用域解析运算符(:::这个运算符用于指定命名空间或类的成员,重载它会破坏语言的命名空间机制。
  3. 三元条件运算符(?::这个运算符的语义非常特定,且重载它可能会导致逻辑上的混乱。
  4. sizeoftypeid运算符:这两个运算符用于获取类型信息,重载它们会破坏语言的类型系统。

能重载的运算符

除了上述不能重载的运算符外,C++中的其他运算符基本都可以被重载。这些运算符包括:

  1. 算术运算符:如+-*/%等,可以用于自定义类型的数值计算。
  2. 关系运算符:如==!=<<=>>=等,可以用于自定义类型的比较操作。
  3. 逻辑运算符:如&&||!等,可以用于自定义类型的逻辑判断。
  4. 位运算符:如&|^~<<>>等,可以用于自定义类型的位操作。
  5. 递增和递减运算符++--,可以用于自定义类型的自增和自减操作。
  6. 赋值运算符:如=+=-=*=/=等,可以用于自定义类型的赋值操作。
  7. 下标运算符[],可以用于自定义类型的数组或容器访问。
  8. 调用运算符(),可以用于自定义类型的函数调用。
  9. 成员访问运算符->,通常用于指针类型的重载,以提供类似智能指针的语法糖。

为什么能重载这些运算符

这些运算符能够被重载的主要原因是,它们都有明确的语义,且重载它们不会破坏语言的基本结构和语义。通过重载这些运算符,我们可以使得自定义类型的对象能够像内置类型一样进行各种操作,从而提高代码的可读性和易用性。

这篇关于运算符重载(Operator Overloading)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/784569

相关文章

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

【重学 MySQL】十九、位运算符的使用

【重学 MySQL】十九、位运算符的使用 示例检查权限添加权限移除权限 在 MySQL 中,位运算符允许你直接在整数类型的列或表达式上进行位级操作。这些操作对于处理那些需要在二进制表示上进行直接修改或比较的场景特别有用,比如权限管理、状态标记等。 &(位与) 对两个数的二进制表示进行位与操作。只有两个相应的二进制位都为 1 时,结果的该位才为 1,否则为 0。 |(位

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

第二十四章 rust中的运算符重载

注意 本系列文章已升级、转移至我的自建站点中,本章原文为:rust中的运算符重载 目录 注意一、前言二、基本使用三、常用运算符四、通用约束 一、前言 C/C++中有运算符重载这一概念,它的目的是让即使含不相干的内容也能通过我们自定义的方法进行运算符操作运算。 比如字符串本身是不能相加的,但由于C++中的String重载了运算符+,所以我们就可以将两个字符串进行相加、但实际

C++可以被重载的操作符Overloadable operators

C++允许绝大多数操作符被重载,也就是重新定义操作符实现的功能,这样它们的行为可以被设计出来以适应所有的数据类型,包括类。 以下是C++可以被重载的操作符(Overloadable operators): //四则运算符+ - * / %+= -= *= /= %=//比较运算符> >= == != //赋值运算符= //位操作

c++/《重载操作符》

为什么要对运算符进行重载:         C++预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型(类)是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对这么运算符进行重新定义,赋予其新的功能,以满足自身的需求。 <返回类型说明符> operator <运算符符号>(<参数表>) { <函数体> }

《C++中的移动构造函数与移动赋值运算符:解锁高效编程的最佳实践》

在 C++的编程世界中,移动构造函数和移动赋值运算符是提升程序性能和效率的重要工具。理解并正确运用它们,可以让我们的代码更加高效、简洁和优雅。 一、引言 随着现代软件系统的日益复杂和对性能要求的不断提高,C++程序员需要不断探索新的技术和方法来优化代码。移动构造函数和移动赋值运算符的出现,为解决资源管理和性能优化问题提供了有力的手段。它们允许我们在不进行不必要的复制操作的情况下,高效地转移资源

Java基础--基本运算符介绍

Java运算符 用于指明对于操作数的运算方式。 分类: 按照操作数的数目来进行分类: 单目a++ 双目a+b 三目(a>b)?x:y; 按照运算符的功能来进行分类: 算术运算:+ - * / %(取余)++ – 如: int x=1; x=x+1;//x空间内的值,自己增加了一个 x++;//x空间内的值,自增一个 ++x;//对于x空间内的值来讲都是一致,最终的结果都自

java基础总结10-面向对象6(方法的重载)

1 方法的重载 方法名一样,但参数不一样,这就是重载(overload)。   所谓的参数不一样,主要有两点:第一是参数的个数不一样,第二是参数的类型不一样。只要这两方面有其中的一方面不一样就可以构成方法的重载了。 package cn.galc.test;public class TestOverLoad {void max(int a, int b) {System.out.prin

【MATLAB】运算符及其优先级

在MATLAB语言中,运算符可以灵活组合以构建更复杂的运算表达式。需要注意的是,与其他高级编程语言类似,MATLAB中的运算符也有优先级。掌握运算优先级有助于我们正确地执行复杂的计算。以下是按照从高到低顺序排列的MATLAB运算符及其优先级列表。 括号 ()。数组的转秩 ( .’ ),数组幂 ( .^ ) ,复转秩 ( ’ ),矩阵幂 ( ^ )。代数正 ( + ),代数负 ( - ),逻辑非