C++运算符的重载

简介: C++运算符的重载

重载的概念

重载(Overloading)不仅仅局限于运算符,在C++中函数也可以重载,只要函数名称相同但参数列表不同,就可以视为重载函数。这样,根据传入的不同参数类型或数量,编译器就能正确识别调用的是哪一个版本的函数。

运算符重载(Operator Overloading)

运算符重载(Operator Overloading)是一种机制,为运算符赋予针对用户自定义类型的特定含义。这意味着我们可以为类或结构体重新定义(重载)运算符的行为,使其能够用于特定类型的对象。这有助于提高代码的清晰度和一致性,使得用户自定义类型的行为看起来更像是内置类型。

运算符重载——复数举例

class Complex {
public:
    double r, i; // 实部和虚部
    // 构造函数和其他成员函数略...
    // 重载加法运算符 '+'
    Complex operator+(const Complex& other) {
        Complex result;
        result.r = this->r + other.r;
        result.i = this->i + other.i;
        return result;
    }
    // 重载输出运算符 '<<',便于输出复数到ostream(如cout)
    friend ostream& operator<<(ostream& os, const Complex& c) {
        os << c.r << "+" << c.i << "i";
        return os;
    }
};
int main() {
    Complex c1{1.0, 2.0};
    Complex c2{3.0, 4.0};
    // 使用重载的加法运算符
    Complex sum = c1 + c2;
    // 使用重载的输出运算符
    cout << "Sum: " << sum << endl;
    return 0;
}

为复数类重载了加法运算符+,使得两个复数对象可以相加,得到一个新的复数对象。同时,我们也重载了输出运算符<<使得复数对象可以像内置类型一样方便地输出到标准输出流(如控制台)。这样,当调用c1 + c2时,会执行我们定义的加法运算符函数,而不是C++内置的加法运算;同样,当我们使用cout << sum时,会调用我们自定义的输出运算符函数来打印复数。

重载运算符的注意点

  1. 只能重载已存在的运算符: 你不能创建新的运算符,只能对C++语言中已经存在的运算符进行重载,如+, -, *, /, ==, !=, <, >, +=, [], ()等。
  2. 至少有一个操作数是用户自定义类型: 当重载二元运算符时(例如+-),至少有一个操作数必须是类或结构类型的对象。也就是说,你不能为内置类型(如intdouble)之间已有的运算符再提供新的含义。
  3. 运算符的语义: 重载后的运算符应保持原有的语义,除非这样做不符合类的设计目标。例如,如果重载+运算符用于两个复数对象相加,那么它应该遵循数学上的加法规则。
  4. 优先级和结合性不可改变: 重载运算符的优先级和结合性仍然是固定的,它们与对应的原始C++运算符保持一致。
  5. 成员函数与非成员函数: 二元运算符可以作为成员函数(有一个隐含的this参数)或非成员函数(接受两个显式的参数)。例如,作为成员函数的operator+只需一个参数,而非成员函数则需要两个。
  6. 特殊运算符: 有些运算符不能被重载,如., .*, ::, ?:, sizeof等。
  7. 操作数的数量和顺序: 重载运算符时,不能更改操作数的数量和顺序。例如,如果原先是二元运算符,重载后也必须是二元的。
  8. 返回类型: 根据运算符的具体语义,返回类型应合理选择,比如+运算符可能返回一个新创建的对象,而赋值运算符=通常返回左侧对象自身的引用以便支持链式赋值。
  9. 异常安全性: 在设计重载运算符时,特别是在处理资源管理类(如智能指针)时,应考虑异常安全性,确保即使在异常抛出的情况下也能正确释放资源。
  10. 短路逻辑: 对于逻辑运算符&&||,重载后将不再具有短路特性,即不论左侧表达式的值如何,右侧都会被执行。
  11. const成员函数: 如果重载的运算符不会修改类的状态,应声明为const成员函数,这样它才能应用于const对象。
  12. 友元函数: 有时需要将运算符重载为类的友元函数,以便访问类的私有和保护成员。
目录
相关文章
|
6月前
|
编译器 C++
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
57 1
|
3月前
|
C++
【C++基础】运算符详解
这篇文章详细解释了C++中运算符的用法,包括算术运算符、赋值运算符、比较运算符和逻辑运算符,以及它们在表达式中的作用和示例。
49 2
|
3月前
|
C++
C++(十九)new/delete 重载
本文介绍了C++中`operator new/delete`重载的使用方法,并通过示例代码展示了如何自定义内存分配与释放的行为。重载`new`和`delete`可以实现内存的精细控制,而`new[]`和`delete[]`则用于处理数组的内存管理。不当使用可能导致内存泄漏或错误释放。
|
4月前
|
C++
c++学习笔记02 运算符
C++学习笔记,介绍了C++中的运算符,包括基本的加减乘除、求模、前后置递增递减、赋值运算符、比较运算符和逻辑运算符的使用及其注意事项。
47 6
|
5月前
|
NoSQL 编译器 Redis
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
|
5月前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
5月前
|
NoSQL Redis C++
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决
|
6月前
|
C++
C++之运算符
C++之运算符
|
6月前
|
安全 程序员 C++
C++一分钟之-重载运算符
【6月更文挑战第21天】C++的运算符重载让程序员能为自定义类型定制运算符行为,增强代码表达力。但要注意清晰性、优先级和返回类型。遵循运算符原有意义,充分测试,并用注释解释非直观设计。示例展示了如何为复数类重载`+`运算符。避免重载内置类型,注意结合性,且慎用隐式转换。重载应提升可读性而非复杂化代码。
51 2
|
6月前
|
C++
C++一分钟之-理解C++的运算符与表达式
【6月更文挑战第18C++的运算符和表达式构成了编程的基础,涉及数学计算、逻辑判断、对象操作和内存管理。算术、关系、逻辑、位、赋值运算符各有用途,如`+`、`-`做加减,`==`、`!=`做比较。理解运算符优先级和结合律至关重要。常见错误包括优先级混淆、整数除法截断、逻辑运算符误用和位运算误解。解决策略包括明确优先级、确保浮点数除法、正确使用逻辑运算符和谨慎进行位运算。通过实例代码学习,如 `(a &gt; b) ? &quot;greater&quot; : &quot;not greater&quot;`,能够帮助更好地理解和应用这些概念。掌握这些基础知识是编写高效、清晰C++代码的关键。
45 3