设计通用复数类 Complex<T>,支持:
real()、imag()conjugate()(a+bi) / (a-bi) 格式#include <iostream>
#include <type_traits>
#include <cmath>
template <typename T>
class Complex {
static_assert(std::is_arithmetic_v, "Complex requires arithmetic type");
T re_, im_;
public:
constexpr Complex(T re = 0, T im = 0) : re_(re), im_(im) {}
// 访问器
constexpr T real() const { return re_; }
constexpr T imag() const { return im_; }
constexpr void real(T v) { re_ = v; }
constexpr void imag(T v) { im_ = v; }
// 共轭
constexpr Complex conjugate() const { return Complex(re_, -im_); }
constexpr void conjugate_self() { im_ = -im_; }
// 运算符重载
constexpr Complex operator+() const { return *this; }
constexpr Complex operator-() const { return Complex(-re_, -im_); }
constexpr Complex& operator+=(const Complex& rhs) { re_ += rhs.re_; im_ += rhs.im_; return *this; }
constexpr Complex& operator-=(const Complex& rhs) { re_ -= rhs.re_; im_ -= rhs.im_; return *this; }
constexpr Complex& operator*=(const Complex& rhs) {
T nr = re_ * rhs.re_ - im_ * rhs.im_;
T ni = re_ * rhs.im_ + im_ * rhs.re_;
re_ = nr; im_ = ni; return *this;
}
constexpr Complex& operator/=(const Complex& rhs) {
T denom = rhs.re_ * rhs.re_ + rhs.im_ * rhs.im_;
if (denom == 0) throw std::domain_error("Division by zero");
T nr = (re_ * rhs.re_ + im_ * rhs.im_) / denom;
T ni = (im_ * rhs.re_ - re_ * rhs.im_) / denom;
re_ = nr; im_ = ni; return *this;
}
// 友元二元运算
friend constexpr Complex operator+(Complex lhs, const Complex& rhs) { return lhs += rhs; }
friend constexpr Complex operator-(Complex lhs, const Complex& rhs) { return lhs -= rhs; }
friend constexpr Complex operator*(Complex lhs, const Complex& rhs) { return lhs *= rhs; }
friend constexpr Complex operator/(Complex lhs, const Complex& rhs) { return lhs /= rhs; }
// 比较
friend constexpr bool operator==(const Complex& lhs, const Complex& rhs) {
return lhs.re_ == rhs.re_ && lhs.im_ == rhs.im_;
}
friend constexpr bool operator!=(const Complex& lhs, const Complex& rhs) { return !(lhs == rhs); }
// 输出流
friend std::ostream& operator<<(std::ostream& os, const Complex& c) {
os << '(' << c.re_;
if (c.im_ >= 0) os << '+';
os << c.im_ << 'i' << ')';
return os;
}
};
// 类型别名
using Complexf = Complex<float>;
using Complexd = Complex<double>;
using Complexld = Complex<long double>;
int main() {
Complexd c1(1, 2), c2(2, 3);
std::cout << "c1 = " << c1 << '\n'; // (1+2i)
std::cout << "c2 = " << c2 << '\n'; // (2+3i)
std::cout << "c1 + c2 = " << c1 + c2 << '\n'; // (3+5i)
std::cout << "c1 - c2 = " << c1 - c2 << '\n'; // (-1-1i)
std::cout << "c1 * c2 = " << c1 * c2 << '\n'; // (-4+7i)
std::cout << "c1 / c2 = " << c1 / c2 << '\n'; // (0.615385+0.0769231i)
std::cout << "conj(c1) = " << c1.conjugate() << '\n'; // (1-2i)
std::cout << "real(c1) = " << c1.real() << ", imag(c1) = " << c1.imag() << '\n';
return 0;
}
static_assert 限制为算术类型,避免误用。+= 等成员函数实现核心逻辑,二元运算符以值传递左值实现(Complex lhs),利用 NRVO/移动语义高效。+,负数自带 -,符合数学习惯。static Complex polar(T r, T theta)。abs (模)、arg (幅角)、exp, log, pow, sqrt。Complexd operator""_i(long double d) { return {0, d}; } 使 3.0_i 直接生成复数。std::complex 互操作:提供转换构造/赋值。复数类是运算符重载、模板约束、值语义设计的绝佳练习。本实现遵循标准库 std::complex 接口风格,且通过 constexpr、异常安全、友元二元运算符等现代 C++ 实践,达到生产可用水平。实际项目中优先直接使用 <complex>,自行实现主要用于教学、嵌入式无标准库环境或特定数值类型扩展。