C++运算符重载

发布时间 2023-03-28 21:51:18作者: Bdathe

C++运算符重载

定义

运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

不能重载的运算符

运算符 说明 不能重载的原因
. 成员运算符 为了保证成员运算符对成员访问的安全性,故不允许重载
.* 成员指针运算符 同上
:: 作用域运算符 因为该运算符左侧是一个类型,而不是一个表达式
?: 三目运算符 C++中没有定义重载三目运算符的语法

除了不能重载的运算符,其余的都可以重载

C++运算符重载的相关规定

  • 1.不能改变运算符的优先级。
  • 2.不能改变运算符的结合性。
  • 3.默认参数不能和重载的运算符一起使用,也就是说,在设计运算符重载成员函数时不能使用默认函数。
  • 4.不能改变运算符的操作数的个数。
  • 5.不能创建新的运算符,只有已有运算符可以被重载
  • 6.运算符作用于C++内部提供的数据类型时,原来含义保持不变

运算符重载的基本格式

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

运算符重载有两种方式:

  • 类内重载(运算符重载函数作为类的成员函数)
  • 类外重载(运算符重载函数作为类的友元函数)

类内重载

在类内声明定义,返回值是本类的对象

/// 成员函数重载加号
/// 
class A {
public:
    /// 重载运算符+号
    /// 类内重载,返回值为本类的对象
    /// 实现类A和int类型相加的一个逻辑
    A operator+(const int a) {
        A test_data;
        test_data.m_data_1 = this->m_data_1 + a;
        test_data.m_data_2 = this->m_data_2 + a;
        return test_data;
    }

private:
    int m_data_1;
    int m_data_2;
};


/// 调用
///
void test() {
    A test_1;
    test_1.m_data_1 = 10;
    test_1.m_data_2 = 20;
    
    A test_2 = test_1 + 10;  /// 本质上是 test_2 = test_1.operator+(10);
                             /// 可以简写成 A test_2 = test_1 + 10;
                             /// 实现了类对象 test_1 和 10 的 + 操作
                             
}

类外重载

在类中声明为友元函数,类外定义,返回值的是一个类的对象。(一般为了能在类外直接调用成员而不用通过成员函数间接调用成员数据)

/// 全局函数重载加号
///
class A {
public:
    friend A operator+(const A test_1, const int test_2);  /// 类内声明友元

private:
    int m_data_1;
    int m_data_2;
};

/// 类外实现友元重载函数
/// 成员函数与全局函数的重载只能保留一个
///
A operator+(const A test_1, const int test_2) {
    A test;
    test.m_data_1 = test_1.m_data_1 + test_2;
    test.m_data_2 = test_1.m_data_2 + test_2;
    return test;
}

/// 调用
///
void test() {
    A test_1;
    test_1.m_data_1 = 10;
    test_1.m_data_2 = 20;
    
    A test_2 = test_1 + 10;  /// 本质上是 test_2 = test_1.operator+(10);
                             /// 可以简写成 A test_2 = operator+(test_1,10);
                             /// 实现了类对象 test_1 和 10 的 + 操作
}

一个细节

在类内重载运算符+号的时候,传入的是一个参数 A operator+(const int a),而在类外重载运算符的时候,传入的是两个参数 friend A operator+(const A test_1, const int test_2),类外很好理解,类内是因为运算符的左操作数是以 this 指针的形式隐式传递给运算符重载函数的,就是这个本质 test_2 = test_1.operator+(10)

注意

类内运算符重载时只能有且仅有一个参数,类外友元运算符重载可以有多个参数

总结:

  • 重载单目运算符时,如果实现为成员函数,则一般需要 0 个参数,如果实现为非成员函数,则一般需要 1 个参数
  • 重载双目运算符时,如果实现为成员函数,则一般需要 1 个参数,如果实现为非成员函数,则一般需要 2 个参数
  • 小括号运算符,参数可以有任意多个
  • 例外情况:后置自增 (减) 运算符,它们虽然是单目运算符。但是因为需要与前置自增 (减) 运算符区别,人为加了个 int 型参数。