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. 友元函数: 有时需要将运算符重载为类的友元函数,以便访问类的私有和保护成员。
目录
相关文章
|
19天前
|
编译器 C++
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)
26 1
|
1月前
|
C++
C++程序中的赋值运算符
C++程序中的赋值运算符
25 2
|
4天前
|
安全 程序员 C++
C++一分钟之-重载运算符
【6月更文挑战第21天】C++的运算符重载让程序员能为自定义类型定制运算符行为,增强代码表达力。但要注意清晰性、优先级和返回类型。遵循运算符原有意义,充分测试,并用注释解释非直观设计。示例展示了如何为复数类重载`+`运算符。避免重载内置类型,注意结合性,且慎用隐式转换。重载应提升可读性而非复杂化代码。
16 2
|
7天前
|
C++
C++一分钟之-理解C++的运算符与表达式
【6月更文挑战第18C++的运算符和表达式构成了编程的基础,涉及数学计算、逻辑判断、对象操作和内存管理。算术、关系、逻辑、位、赋值运算符各有用途,如`+`、`-`做加减,`==`、`!=`做比较。理解运算符优先级和结合律至关重要。常见错误包括优先级混淆、整数除法截断、逻辑运算符误用和位运算误解。解决策略包括明确优先级、确保浮点数除法、正确使用逻辑运算符和谨慎进行位运算。通过实例代码学习,如 `(a &gt; b) ? &quot;greater&quot; : &quot;not greater&quot;`,能够帮助更好地理解和应用这些概念。掌握这些基础知识是编写高效、清晰C++代码的关键。
16 3
|
1月前
|
C++ 编译器
|
29天前
|
C++
c++运算符
c++运算符
28 2
|
1月前
|
编译器 C语言 C++
【C++】基础知识讲解(命名空间、缺省参数、重载、输入输出)
【C++】基础知识讲解(命名空间、缺省参数、重载、输入输出)
15 1
【C++】基础知识讲解(命名空间、缺省参数、重载、输入输出)
|
29天前
|
程序员 编译器 C++
c++重载运算符和重载函数
c++重载运算符和重载函数
26 1
|
1月前
|
存储 安全 程序员
C++中的四种类型转换运算符
reinterpret_cast` 则是非常危险的类型转换,仅用于二进制级别的解释,不检查安全性。`dynamic_cast` 用于类的继承层次间转换,向上转型总是安全的,向下转型时会借助 RTTI 进行安全性检查。只有当转换路径在继承链内时,转换才会成功。
13 1
|
1月前
|
编译器 C++
【C++】类与对象(运算符重载、const成员、取地址重载)
【C++】类与对象(运算符重载、const成员、取地址重载)
24 2