首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C++ 复数类模板实现:四则运算、共轭与输出格式化

     編輯:關於C語言

需求分析

设计通用复数类 Complex<T>,支持:

  1. 构造:实部、虚部
  2. 运算:加、减、乘、除
  3. 访问:real()、imag()
  4. 共轭:conjugate()
  5. 输出:标准 (a+bi) / (a-bi) 格式

完整实现(C++17)

#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 限制为算术类型,避免误用。
  • constexpr:支持编译期计算,零开销抽象。
  • 复合赋值为基础:+= 等成员函数实现核心逻辑,二元运算符以值传递左值实现(Complex lhs),利用 NRVO/移动语义高效。
  • 除法保护:分母模平方为 0 抛异常,避免未定义行为。
  • 输出格式:虚部非负显式输出 +,负数自带 -,符合数学习惯。
  • 无动态分配:纯值类型,适合 STL 容器、向量化计算。

常见扩展

  • 极坐标构造: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>,自行实现主要用于教学、嵌入式无标准库环境或特定数值类型扩展。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved