章节目录

第21章总结

本节阅读量:

在本章中,我们探讨了与运算符重载相关的主题,以及重载类型转换,以及与拷贝构造函数相关的主题。


总结

运算符重载是函数重载的一种变体,它允许为类重载运算符。当运算符重载时时,意图应尽可能接近运算符的原始意图。如果运算符符在应用于自定义类时的含义不明确和直观,请使用命名成员函数。

运算符可以重载为普通函数、友元函数或成员函数。以下经验法则可以帮助您确定哪种形式最适合给定的情况:

  1. 如果重载赋值(=)、下标([])、函数调用(())或成员选择(->),请作为成员函数进行重载。
  2. 如果要重载一元运算符,请作为成员函数进行重载。
  3. 如果重载修改其左操作数的二元运算符(例如,运算符+=),请尽可能作为成员函数进行重载。
  4. 如果要重载不修改其左操作数的二元运算符(例如,运算符+),请作为普通函数或友元函数进行重载。

可以重载类型转换以提供转换函数,这些函数可以用于将类显式或隐式转换为另一种类型。

拷贝构造函数是一种特殊类型的构造函数,用于从相同类型的另一个对象初始化对象。拷贝构造函数用于从相同类型的对象进行直接/统一初始化、拷贝初始化(Fraction f = Fraction(5,3))以及按值传递或返回参数时。

如果不提供拷贝构造函数,编译器将为您创建一个默认的。编译器提供的拷贝构造函数将使用成员级初始化,这意味着副本的每个成员都是从原始成员初始化的。出于优化目的,拷贝构造函数可能会被省略,即使它有副作用,因此不要依赖于拷贝构造函数的实际执行。

默认情况下,构造函数被视为转换构造函数,这意味着编译器将使用它们隐式地将其他类型的对象转换为类的对象。通过在构造函数前面使用explict关键字,可以避免这种情况。您还可以删除类中的函数,包括拷贝构造函数和重载赋值运算符(如果需要)。如果调用已删除的函数,这将导致编译错误。

可以重载赋值运算符以允许对类进行赋值。如果不提供重载赋值运算符,编译器将为您创建一个默认的。重载赋值运算符应该始终包括自赋值检查。

新程序员在使用赋值运算符与拷贝构造函数时经常会混淆,但这相当简单:

  1. 如果在复制之前必须创建新对象,则使用拷贝构造函数(注意:这包括按值传递或返回对象)。
  2. 如果在复制之前不必创建新对象,则使用赋值运算符。

默认情况下,编译器提供的拷贝构造函数和赋值运算符执行成员级初始化或赋值,这是浅拷贝。如果类动态分配内存,这可能会导致问题,因为多个对象最终将指向相同的已分配内存。在这种情况下,您需要显式定义这些函数,以便进行深拷贝。更好的是,如果可以,请避免自己进行内存管理,并使用标准库中的类。


21.13 重载运算符和函数模板

上一节

22.0 智能指针和移动语义简介

下一节