题目

编写程序,设计数学复数类 Complex(实部 real、虚部 imag)。完整重载算术双目运算符 operator+、operator-、operator* 以及复合赋值运算符 operator+=。遵循工业级 C++ 最佳实践:将 += 实现为成员函数,并基于 += 将 + 实现为非成员(非侵入式)友元/全局函数,天然支持与普通浮点数(如 3.5 + c)进行对称隐式混合运算。

输入格式:无需外部输入。

输出格式:输出复数相加、相乘与实数混合算术的计算验证结果。

数据范围与约定:运算符重载范式、非成员运算符对称性、基于复合运算符实现算术运算符。

思路与算法

1. 为什么算术运算符要设计为非成员函数
若 operator+ 是成员函数,c + 2.0 等价于 c.operator+(2.0) 可以编译;但 2.0 + c 会编译失败,因为左操作数是 double,无法调用成员函数。声明为非成员全局函数时,编译器会对左操作数和右操作数同等施加隐式转换,完美实现加法的交换律对称性。

2. 基于 += / -= 实现 + / - 的设计模式
先实现就地修改的成员 operator+= 与 operator-=;再以非成员 operator+ / operator- 对左操作数按值拷贝后复用复合赋值,同时保证 5.0 + c 这类对称混合运算可以编译。

3. 复数乘法公式
\((a + bi)(c + di) = (ac - bd) + (ad + bc)i\)。

完整程序

#include <iostream>
#include <string>
#include <cmath>

class Complex {
private:
    double real_;
    double imag_;

public:
    // 允许由单个 double 隐式转换构造
    Complex(double r = 0.0, double i = 0.0) : real_(r), imag_(i) {}

    // 1. 复合赋值运算符(成员函数,返回自身引用)
    Complex& operator+=(const Complex& rhs) {
        real_ += rhs.real_;
        imag_ += rhs.imag_;
        return *this;
    }

    Complex& operator-=(const Complex& rhs) {
        real_ -= rhs.real_;
        imag_ -= rhs.imag_;
        return *this;
    }

    Complex& operator*=(const Complex& rhs) {
        double r = real_ * rhs.real_ - imag_ * rhs.imag_;
        double i = real_ * rhs.imag_ + imag_ * rhs.real_;
        real_ = r;
        imag_ = i;
        return *this;
    }

    // 2. 对称算术运算符(非成员友元函数,天然支持混合类型交换律)
    friend Complex operator+(Complex lhs, const Complex& rhs) {
        lhs += rhs;
        return lhs;
    }

    friend Complex operator-(Complex lhs, const Complex& rhs) {
        lhs -= rhs;
        return lhs;
    }

    friend Complex operator*(Complex lhs, const Complex& rhs) {
        lhs *= rhs;
        return lhs;
    }

    void print(const std::string& label) const {
        std::cout << label << " = " << real_ 
                  << (imag_ >= 0 ? " + " : " - ") << std::abs(imag_) << "i\n";
    }
};

int main() {
    Complex c1(3.0, 4.0);  // 3 + 4i
    Complex c2(1.0, -2.0); // 1 - 2i

    c1.print("复数 c1");
    c2.print("复数 c2");

    std::cout << "\n--- 1. 复数间加法、减法与乘法 ---\n";
    Complex sum = c1 + c2;
    sum.print("c1 + c2");

    Complex diff = c1 - c2;
    diff.print("c1 - c2");

    Complex prod = c1 * c2;
    prod.print("c1 * c2 (期望: 11 - 2i)");

    std::cout << "\n--- 2. 验证非成员运算符的对称混合运算 ---\n";
    Complex mixed1 = c1 + 5.0; // 复数 + 实数
    Complex mixed2 = 5.0 + c1; // 实数 + 复数 (成员函数无法做到的对称调用)
    mixed1.print("c1 + 5.0");
    mixed2.print("5.0 + c1");

    return 0;
}

运行示例

输出:

复数 c1 = 3 + 4i
复数 c2 = 1 - 2i

--- 1. 复数间加法、减法与乘法 ---
c1 + c2 = 4 + 2i
c1 - c2 = 2 + 6i
c1 * c2 (期望: 11 - 2i) = 11 - 2i

--- 2. 验证非成员运算符的对称混合运算 ---
c1 + 5.0 = 8 + 4i
5.0 + c1 = 8 + 4i