面试题:什么是 C++ 的运算符重载?

C++ 中的运算符重载(Operator Overloading)是一种允许用户自定义类类型对象的运算符行为的特性。通过运算符重载,可以使自定义类型的对象像内置类型一样使用运算符(如 +-*/ 等)。


1. 运算符重载的基本概念

  • 目的:让自定义类型的对象支持内置运算符,使代码更直观和易读。
  • 实现方式:通过定义特殊的成员函数或全局函数来重载运算符。
  • 限制
    • 不能重载内置类型的运算符(如 intfloat 等)。
    • 不能创建新的运算符(如 ** 表示幂运算)。
    • 部分运算符不能重载(如 ::..*?: 等)。

2. 运算符重载的语法

运算符重载可以通过成员函数或全局函数实现。

(1)成员函数形式

  • 运算符重载函数是类的成员函数。
  • 例如,重载 + 运算符:
  class Complex {
  private:
      double real, imag;
  public:
      Complex(double r = 0, double i = 0) : real(r), imag(i) {}

      // 重载 + 运算符(成员函数)
      Complex operator+(const Complex& other) const {
          return Complex(real + other.real, imag + other.imag);
      }
  };

  Complex a(1, 2), b(3, 4);
  Complex c = a + b; // 调用 operator+

(2)全局函数形式

  • 运算符重载函数是全局函数,通常需要声明为类的友元以访问私有成员。
  • 例如,重载 + 运算符:
  class Complex {
  private:
      double real, imag;
  public:
      Complex(double r = 0, double i = 0) : real(r), imag(i) {}

      // 声明友元函数
      friend Complex operator+(const Complex& a, const Complex& b);
  };

  // 重载 + 运算符(全局函数)
  Complex operator+(const Complex& a, const Complex& b) {
      return Complex(a.real + b.real, a.imag + b.imag);
  }

  Complex a(1, 2), b(3, 4);
  Complex c = a + b; // 调用 operator+

3. 常用运算符的重载示例

(1)算术运算符

  • 例如,重载 +-*/ 等。
  class Complex {
  private:
      double real, imag;
  public:
      Complex(double r = 0, double i = 0) : real(r), imag(i) {}

      // 重载 + 运算符
      Complex operator+(const Complex& other) const {
          return Complex(real + other.real, imag + other.imag);
      }

      // 重载 - 运算符
      Complex operator-(const Complex& other) const {
          return Complex(real - other.real, imag - other.imag);
      }
  };

(2)关系运算符

  • 例如,重载 ==!=<> 等。
  class Complex {
  private:
      double real, imag;
  public:
      Complex(double r = 0, double i = 0) : real(r), imag(i) {}

      // 重载 == 运算符
      bool operator==(const Complex& other) const {
          return real == other.real && imag == other.imag;
      }

      // 重载 != 运算符
      bool operator!=(const Complex& other) const {
          return !(*this == other);
      }
  };

(3)赋值运算符

  • 例如,重载 =
  class Complex {
  private:
      double real, imag;
  public:
      Complex(double r = 0, double i = 0) : real(r), imag(i) {}

      // 重载 = 运算符
      Complex& operator=(const Complex& other) {
          if (this != &other) { // 防止自赋值
              real = other.real;
              imag = other.imag;
          }
          return *this;
      }
  };

(4)流插入和提取运算符

  • 例如,重载 <<>>
  #include <iostream>
  class Complex {
  private:
      double real, imag;
  public:
      Complex(double r = 0, double i = 0) : real(r), imag(i) {}

      // 声明友元函数
      friend std::ostream& operator<<(std::ostream& os, const Complex& c);
      friend std::istream& operator>>(std::istream& is, Complex& c);
  };

  // 重载 << 运算符
  std::ostream& operator<<(std::ostream& os, const Complex& c) {
      os << "(" << c.real << ", " << c.imag << ")";
      return os;
  }

  // 重载 >> 运算符
  std::istream& operator>>(std::istream& is, Complex& c) {
      is >> c.real >> c.imag;
      return is;
  }

  Complex c;
  std::cin >> c;  // 输入
  std::cout << c; // 输出

4. 运算符重载的注意事项

  • 保持语义一致性:重载的运算符应与其原始语义一致(如 + 用于加法,- 用于减法)。
  • 避免过度重载:不要滥用运算符重载,以免降低代码可读性。
  • 处理自赋值:在重载赋值运算符时,注意处理自赋值情况。

5. 总结

  • 运算符重载是 C++ 中强大的特性,允许自定义类型支持内置运算符。
  • 可以通过成员函数或全局函数实现运算符重载。
  • 常用的运算符(如算术、关系、赋值、流插入/提取)都可以重载。
  • 使用运算符重载时,应保持语义一致性并避免过度使用。

通过合理使用运算符重载,可以使代码更直观、简洁和易读。

THE END
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容