C++ 运算符重载

2025 年 8 月 29 日 | 阅读 8 分钟

运算符重载是 C++ 中的重要特性之一。它是一种编译时多态性。它用于修改某些运算符(例如 C++ 中的 '+'、'-'、'==' 和 '*')的默认行为。

它使我们能够将“+”、“-”、“*”运算符与用户定义的类对象一起使用,从而促进涉及这些对象的操作。可以重载算术运算符的其他类实例包括分数、大整数、复数等等。

语法

它具有以下语法:

在此语法中

  • 返回类型:重载运算符应始终具有返回类型。
  • 重载运算符可以带一个或多个参数。
  • 运算符可以作为成员函数或非成员函数(友元函数)重载。

使用 C++ 运算符重载的简单示例

示例

编译并运行

输出

Enter the first fraction: Enter the numerator : 3
Enter the denominator : 4
Enter the second fraction:nEnter the numerator : 2
Enter the denominator: 5
The fraction is  6/ 20

说明

此 C++ 程序实现了表示分数的类“Fract”并重载了乘法运算符。该类包含私有元素“a1”(分子)和“b1”(分母)。

乘法运算符在“operatior*”函数中被重载,该函数通过将两个分数的分子和分母相乘来计算两个分数的乘积。主函数创建两个分数对象,获取用户输入,并计算这两个分数的乘积。

C++ 运算符重载规则

有几条规则有助于理解 C++ 中的运算符重载。

  • 如果我们要使用运算符重载,则至少一个操作数应该是一个用户定义的类对象。
  • 我们只能重载现有运算符。我们不能重载新运算符。
  • 在 C++ 中,某些运算符不能使用友元函数重载。但是,这些运算符可以在成员函数的帮助下重载。

C++ 中运算符重载的类型

运算符重载的几种类型如下

1. 一元运算符重载

在 C++ 中,一元运算符重载函数是一种运算符重载,它对单个操作数执行其任务。

C++ 一元运算符重载示例

让我们举一个例子来说明 C++ 中的一元运算符重载。

示例

编译并运行

输出

The value before decrement: The Value: 15
The value after decrement: The Value: 14

说明

上面的 C++ 代码旨在重载前缀递减运算符 (--)。Decrement 类有一个名为 "val" 的整型私有成员,由构造函数设置。前缀递减运算符通过成员函数 operator() 实现,该函数将 'val' 的值减一并返回当前对象。

2. 二元运算符重载

在 C++ 二元运算符重载函数中,只能传递一个参数。它是一种对两个操作数执行任务的运算符重载。

C++ 二元 (+) 运算符重载示例

让我们举一个例子来演示 C++ 中的二元 (+) 运算符重载。

示例

编译并运行

输出

Enter the First Cmplex Number: 4.7 + 2.8i
Enter the Second Complex Number: 3.5 + 5.7i
Sum of both Numbers: 8.2 + 8.5i

说明

在此示例中,我们创建了一个 Complex 类,然后创建了两个私有数据成员 real_num 和 imag_num。之后,我们使用一个带默认值的参数化构造函数。它将复数初始化为 real_num + imag_num * i。接下来,我们使用程序中的二元 + 运算符来打印两个复数的和。

3. 使用友元函数进行二元运算符重载

在 C++ 中,使用友元函数进行二元运算符重载时,运算符重载函数应在友元函数之前可用。此外,该函数必须在类作用域中声明。在二元运算符中,友元函数通常接受两个不同的参数,并借助一元运算符修改一个参数。

C++ 使用友元函数进行二元运算符重载示例

让我们举一个例子来演示 C++ 中使用友元函数进行二元运算符重载。

示例

编译并运行

输出

Factorial of 5 is: 120
Factorial of 4 is: 24
Product of factorials: 2880

说明

在此示例中,我们定义了一个 Factorial_Of_Number 类,该类计算给定数字的阶乘。之后,我们将使用友元函数进行二元运算符重载来重载 * 运算符。

当两个类对象相乘时,友元函数访问它们的私有 fact 值并返回一个新对象,该对象包含这些阶乘的乘积。display() 函数显示阶乘,displayProduct() 函数显示最终输出。

C++ 中哪些运算符可以重载,哪些不能重载?

在 C++ 中,当涉及到一元和二元运算符的重载时,并非每个运算符都可以重载,有些必须保持不变。

可重载运算符是可以重新定义以与用户定义类型一起使用的运算符,而不可重载运算符是不能重载的运算符,因为它们是语言的基础。

以下是 C++ 中不能重载的运算符列表。

  • 三元(条件)运算符 (? :)
  • 成员访问(点)运算符 (.)
  • 指向成员的指针运算符 (.*)
  • 作用域解析运算符 (::)
  • 类型识别运算符 (typeid)
  • 大小运算符 (sizeof)

C++ 中的特殊运算符可以进行运算符重载。

C++ 中的特殊运算符重载

C++ 中有各种运算符可以重载以用于用户定义数据类型。这些包括以下一组运算符。

  • new:它用于声明指针变量并在程序执行时为其分配内存。
  • delete:此运算符释放已分配给指针变量的内存。
  • [](下标):此运算符允许从数组中选择特定值。
  • (成员访问):它允许通过指针选择类的变量成员。
  • =(赋值):此运算符用于将数据从一个对象复制到另一个对象。
  • ()(函数调用):此运算符使每个对象都能够充当函数。

重载这些运算符简化了对象之间交互的设计,提高了 C++ 编程环境的效率和灵活性。

C++ 中运算符重载的优点

C++ 中运算符重载的几个优点如下

  • 提高清晰度:程序员将有机会使用更易懂的语法,这由于运算符重载而增加了代码的清晰度和可理解性。
  • 提高可维护性:它允许用户定义类型像基本类型一样工作,从而减少问题并提供更好的维护。
  • 支持代码重用:将运算符应用于其他不同对象的可能性增加了可重用性的支持。
  • 抽象和封装:运算符重载是面向对象编程的一个特性,并通过数据的抽象和封装得到促进。

C++ 中运算符重载的缺点

C++ 中运算符重载的几个缺点如下

  • 潜在的滥用:可以以导致冗余或使实现更难理解的方式定义重载运算符。
  • 增加难度:由于先前定义的目的,重载似乎会使应用程序更加复杂,从而引入混乱和需要解决的额外问题。
  • 重载限制:在 C++ 中,不可能重载所有运算符,例如成员访问运算符。

结论

总之,运算符重载使自定义用户定义类型能够像内置类型一样工作,从而增强了代码的可读性、可重用性和易维护性。它为已定义类提供了运算符的用户特定修改,以帮助相对轻松地解决复杂问题。

C++ 运算符重载 MCQ

1. C++ 中可以重载赋值 (=) 运算符吗?

  1. 不能
  2. 是的,作为友元函数
  3. 是的,作为成员函数
  4. 是的,但只能作为非成员函数
 

答案: c) 是的,作为成员函数


2. C++ 中哪些运算符必须重载为类成员函数?

  1. ==
  2. =
  3. +
  4. <<
 

答案: b) =


3. 以下关于 C++ 中友元函数运算符的说法哪一项是正确的?

  1. 它们必须在类中定义
  2. 它们可以访问类的私有成员
  3. 它们比成员函数慢
  4. 它们只能重载一元运算符
 

答案: b) 它们可以访问类的私有成员


4. 以下运算符函数重载了什么?

Bool operator== (const MyClass &obj);

  1. 相等性比较
  2. 加法
  3. 赋值
  4. 逻辑与
 

答案: a) 相等比较


5. C++ 中以下哪些运算符可以重载?

  1. ?:
  2. sizeof
  3. .
  4. +
 

答案: d) +