【问题标题】:problem with operator+ priority in making a HyperComplex class制作 HyperComplex 类时 operator+ 优先级的问题
【发布时间】:2021-06-08 17:13:38
【问题描述】:

我正在制作一个 HyperComplex 类只是为了练习,我遇到了 2 个 HyperComplex 变量之间的 operator+ 行为问题,我得到了常规的复杂 operator+, 我还尝试做 2 个操作员+(1 个带有 Hc 和 Complex,第二个带有 complex 和 Hc,但这给了我模棱两可的 eroor)

这是我的代码:

class Complex {
public:
 Complex(const T& real = 0, const T& imaginary = 0);
 Complex(const Complex&) = default;
 virtual ~Complex() {};
 Complex& operator=(const Complex&) = default;
 Complex& operator+=(const Complex&);
 }
protected:
 T real;
 T imaginary;
};

template <class T>
Complex<T>& Complex<T>::operator+=(const Complex<T>& rhs){
    real += rhs.real;
    imaginary += rhs.imaginary;
    return *this;
}

template <class T>
Complex<T> operator+(const Complex<T>& lhs, const Complex<T>& rhs){
    Complex<T> tmp = lhs;
    return tmp += rhs; 
}

template <class T>
class HyperComplex: public Complex<T> {
    private:
    T j_part;
    public :
    HyperComplex(const T& real = 0, const T& imaginary = 0, const T& j_part = 0): Complex<T>(real,imaginary), j_part(j_part) {}    
    HyperComplex(const HyperComplex&) = default;                                      
    HyperComplex(const Complex<T>& p): Complex<T>(p) , j_part(0) {
        const HyperComplex* ptr = dynamic_cast<const HyperComplex*>(&p);
        if (ptr != nullptr){
            j_part = ptr->j_part;
        }
    }    // copy ctor gets ref to complex
    HyperComplex<T>& operator+=(const HyperComplex<T>& rhs){
        this->real += rhs.real;
        this->imaginary += rhs.imaginary;
        j_part += rhs.j_part;
        return *this;
    }

};

template <class T>
HyperComplex<T> operator+(const HyperComplex<T>& lhs, const Complex<T>& rhs){
    HyperComplex<T> tmp = lhs;
    return tmp += rhs; 
}

template <class T>
HyperComplex<T> operator+(const Complex<T>& lhs, const HyperComplex<T>& rhs){
    HyperComplex<T> tmp = rhs;
    return tmp += lhs; 
}

当我运行这段代码时:

   HyperComplex<int> hc(4,2,4) ;
    HyperComplex<int> hc1 = hc + hc;
    HyperComplex<int> hc2 = c2;
    HyperComplex<int> hc3 = hc + c2;
    HyperComplex<int> hc4 = c2 + hc;

我在 hc1 calc 中变得模棱两可

【问题讨论】:

  • 代码太多了。通过删除与您的问题不直接相关的所有内容来制作一个最小示例。
  • 谢谢约翰,我修好了

标签: c++ class templates operator-overloading overloading


【解决方案1】:

问题已解决!解决方案是 4 个不同的 operator+:

Complex<T> operator+(const Complex<T>& lhs, const Complex<T>& rhs){
    Complex<T> tmp = lhs;
    return tmp += rhs; 
}

template <class T>
HyperComplex<T> operator+(const HyperComplex<T>& lhs, const Complex<T>& rhs){
    HyperComplex<T> tmp = lhs;
    return tmp += rhs; 
}

template <class T>
HyperComplex<T> operator+(const Complex<T>& lhs, const HyperComplex<T>& rhs){
    HyperComplex<T> tmp = rhs;
    return tmp += lhs; 
}

template <class T>
HyperComplex<T> operator+(const HyperComplex<T>& lhs, const HyperComplex<T>& rhs){
    HyperComplex<T> tmp = rhs;
    return tmp += lhs; 
}

【讨论】:

    【解决方案2】:

    对于初学者来说,类模板 Complex 的析构函数应该是虚拟的

    virtual ~Complex() = default;
    

    制作这个构造函数

    HyperComplex(const Complex<T>& p);
    

    显式

    explicit HyperComplex(const Complex<T>& p);
    

    否则Complex 类型的对象可以隐式转换为HyperComplex 类型的对象,反之亦然。

    因此,无论是运营商

    template <class T>
    Complex<T> operator+(const Complex<T>& lhs, const Complex<T>& rhs){
        Complex<T> tmp = lhs;
        return tmp += rhs; 
    }
    

    或运营商

    template <class T>
    HyperComplex<T> operator+(const HyperComplex<T>& lhs, const HyperComplex<T>& rhs){
        HyperComplex<T> tmp = lhs;
        return tmp += rhs; 
    }
    

    可以在这些语句中调用

    HyperComplex<int> hc3 = hc + c2;
    HyperComplex<int> hc4 = c2 + hc;
    

    另一种方法是显式声明另外两个运算符,例如

    template <class T>
    HyperComplex<T> operator+(const HyperComplex<T>& lhs, const Complex<T>& rhs);
    

    template <class T>
    HyperComplex<T> operator+(const Complex<T>& lhs, const HyperComplex<T>& rhs);
    

    但是在任何情况下,具有默认参数的类的构造函数都应该被声明为显式的。

    【讨论】:

    • 嗨,但这不是我的意思。我希望这行代码可以工作:HyperComplex&lt;int&gt; hc2 = c2;
    • @Tuxedo 你可以改写 HyperComplex hc2( c2 );
    • 我正在寻找一种无需铸件即可自然工作的方法,但谢谢
    • 来自莫斯科的@Tuxedo Vlad 还说您可以提供另外两个重载Complex&lt;T&gt; + HyperComplex&lt;T&gt;HyperComplex&lt;T&gt; + Complex&lt;T&gt;。如果您想要隐式转换,这就是成本。
    • 这样做并从编译器得到模棱两可的错误
    猜你喜欢
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多