题目
编写程序,设计数学复数类 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