如何在申报过程中将运算分配给复数?

How to assign an operation to a complex number during the declaration?

提问人: 提问时间:6/14/2019 最后编辑:Vlad from Moscow 更新时间:6/14/2019 访问量:97

问:

我正在为复数编写一个类,当我声明其中一个类时,我必须在为它分配操作之前且仅在我为其分配操作之后声明它。


例如:

这有效

ComplexNumber Number;  
Number = AnotherComplex + (or -) AgainAnotherComplex;  

这不起作用

ComplexNumber Number = AnotherComplex + (or -) AgainAnotherComplex;

我在这里留下的是 .h 文件

#ifndef COMPLEX_NUMBERS_H_INCLUDED
#define COMPLEX_NUMBERS_H_INCLUDED

#include <iostream> // for std namespace

class ComplexNumber
{
    public:
        ComplexNumber();
        ComplexNumber(float RealPart, float ImaginaryPart);
        ComplexNumber(ComplexNumber &NewComplexNumber);
        ~ComplexNumber();
        void SetRealPart(float RealPart);
        void SetImaginaryPart(float ImaginaryPart);
        friend ComplexNumber operator+(const ComplexNumber Complex1, const ComplexNumber Complex2);
        friend ComplexNumber operator-(const ComplexNumber Complex1, const ComplexNumber Complex2);
        friend std::ostream & operator<<(std::ostream &output, const ComplexNumber &NumberToDsiplay);
        friend std::istream & operator >>(std::istream &input, ComplexNumber &NumberToInput);
        bool operator==(const ComplexNumber Complex);
        bool operator!=(const ComplexNumber Complex);

    private:
        float RealPart;
        float ImaginaryPart;
};

#endif // COMPLEX_NUMBERS_H_INCLUDED

我还在这里留下了.cpp文件

#include "Complex Numbers.h"

ComplexNumber::ComplexNumber()
{
    RealPart = 0;
    ImaginaryPart = 0;
}

ComplexNumber::ComplexNumber(float RealPart, float ImaginaryPart)
{
    SetRealPart(RealPart);
    SetImaginaryPart(ImaginaryPart);
}

ComplexNumber::~ComplexNumber()
{
}

ComplexNumber::ComplexNumber(ComplexNumber &NewComplexNumber)
{
    RealPart = NewComplexNumber.RealPart;
    ImaginaryPart = NewComplexNumber.ImaginaryPart;
}

void ComplexNumber::SetRealPart(float RealPart)
{
    this->RealPart=RealPart;
}

void ComplexNumber::SetImaginaryPart(float ImaginaryPart)
{
    this->ImaginaryPart=ImaginaryPart;
}

ComplexNumber operator+(const ComplexNumber Complex1, const ComplexNumber Complex2)
{
    ComplexNumber TemporaryComplexNumber;
    TemporaryComplexNumber.RealPart = Complex1.RealPart + Complex2.RealPart;
    TemporaryComplexNumber.ImaginaryPart = Complex1.ImaginaryPart + Complex2.ImaginaryPart;

    return TemporaryComplexNumber;
}

ComplexNumber operator-(const ComplexNumber Complex1, const ComplexNumber Complex2)
{
    ComplexNumber TemporaryComplexNumber;
    TemporaryComplexNumber.RealPart = Complex1.RealPart - Complex2.RealPart;
    TemporaryComplexNumber.ImaginaryPart = Complex1.ImaginaryPart - Complex2.ImaginaryPart;

    return TemporaryComplexNumber;
}


std::ostream & operator<<(std::ostream &output, const ComplexNumber &NumberToDsiplay)
{
    if(NumberToDsiplay.ImaginaryPart > 0)
        output << std::endl << NumberToDsiplay.RealPart << "+" << NumberToDsiplay.ImaginaryPart << "i";
    else if(NumberToDsiplay.ImaginaryPart < 0)
        output << std::endl << NumberToDsiplay.RealPart << "" << NumberToDsiplay.ImaginaryPart << "i";
    else if(NumberToDsiplay.ImaginaryPart == 0)
        output << std::endl << NumberToDsiplay.RealPart << "  (The imaginary part is equal to 0)";
    return output;
}

std::istream & operator >>(std::istream &input, ComplexNumber &NumberToInput)
{
    std::cout << "Enter the real part: ";
    input >> NumberToInput.RealPart;
    std::cout << "Enter the imaginary part: ";
    input >> NumberToInput.ImaginaryPart;
}

bool ComplexNumber::operator==(const ComplexNumber Complex)
{
    return RealPart==Complex.RealPart && ImaginaryPart==Complex.ImaginaryPart;
}

bool ComplexNumber::operator!=(const ComplexNumber Complex)
{
    if(RealPart != Complex.RealPart && ImaginaryPart != Complex.ImaginaryPart)
            return true;
    else if(RealPart != Complex.RealPart && (!(ImaginaryPart != Complex.ImaginaryPart)))
            return true;
    else if(ImaginaryPart != Complex.ImaginaryPart && (!(RealPart != Complex.RealPart)))
        return true;

    return false;
}
C++ 引用 运算符重载 复制构造函数 complex-numbers

评论

6赞 KamilCuk 6/14/2019
注意:你可以只使用 . - 如何检测“不起作用”状态?它会编译吗?有什么警告吗?错误?它会抛出异常吗?结果与你所期望的不一样?很可能你缺少构造函数。std::complex<float>This doesn't work:ComplexNumber(const ComplexNumber& NewComplexNumber);
2赞 Ted Lyngmo 6/14/2019
您的头文件名 () 中真的有空格吗?"Complex Numbers.h"
1赞 Marek R 6/14/2019
const在复制 CTOR 中缺失,默认一个将完成这项工作。
0赞 6/14/2019
我添加了 const 关键字,现在它可以工作了,谢谢@KamilCuk
1赞 molbdnilo 6/14/2019
更方便的实现是 。operator!=return !(*this == Complex);

答:

4赞 Vlad from Moscow 6/14/2019 #1

只需声明复制构造函数,例如

ComplexNumber( const ComplexNumber &NewComplexNumber);
               ^^^^^

否则,编译器无法将非常量引用绑定到作为表达式结果的临时引用

AnotherComplex + (or -) AgainAnotherComplex

调用任一运算符

    friend ComplexNumber operator+(const ComplexNumber Complex1, const ComplexNumber Complex2);
    friend ComplexNumber operator-(const ComplexNumber Complex1, const ComplexNumber Complex2);

反过来,它应该被声明为

    friend ComplexNumber operator+(const ComplexNumber &Complex1, const ComplexNumber &Complex2);
    friend ComplexNumber operator-(const ComplexNumber &Complex1, const ComplexNumber &Complex2);

也就是说,参数应该是引用类型。

而这个运算符定义

bool ComplexNumber::operator!=(const ComplexNumber Complex)
{
    if(RealPart != Complex.RealPart && ImaginaryPart != Complex.ImaginaryPart)
            return true;
    else if(RealPart != Complex.RealPart && (!(ImaginaryPart != Complex.ImaginaryPart)))
            return true;
    else if(ImaginaryPart != Complex.ImaginaryPart && (!(RealPart != Complex.RealPart)))
        return true;

    return false;
}

没有多大意义。

像这样定义它

bool ComplexNumber::operator!=(const ComplexNumber &Complex) const
{
    return not( *this == Complex );
}

注意参数列表后面的限定符。您需要添加到 的相同限定符。constoperator ==

评论

0赞 TrebledJ 6/14/2019
我很少看到在课堂上被用作成员。更普遍的往往是 .我想知道使用前者是否有任何好处,即与操作员+交友?friend ComplexNumber operator+(const ComplexNumber& Complex1, const ComplexNumber& Complex2);ComplexNumber operator+(const ComplexNumber& complex2) const;
0赞 Vlad from Moscow 6/14/2019
@TrebledJ 通常,二进制运算符被声明为友元函数,以允许隐式转换。
0赞 TrebledJ 6/14/2019
啊,真甜。很高兴知道。:-)
4赞 melpomene 6/14/2019 #2

in 声明不是赋值。=

ComplexNumber a = b + c;

只是另一种写作方式

ComplexNumber a(b + c);

即,它通过调用复制构造函数进行初始化。ab + c

复制构造函数声明为

    ComplexNumber(ComplexNumber &NewComplexNumber);

它通过引用来获取其论点。引用不能绑定到临时值,例如表达式的结果(例如,)。a + ba - b

修复:

    ComplexNumber(const ComplexNumber &NewComplexNumber);

根据经验,复制构造函数应始终通过常量引用来获取其参数。

3赞 Gilles-Philippe Paillé 6/14/2019 #3

添加 const copy 构造函数:

ComplexNumber::ComplexNumber(const ComplexNumber & NewComplexNumber)

该行调用类的复制构造函数。但是,结果是 r 值,而您提供的唯一复制构造函数仅采用 l 值。ComplexNumber Number = a + b;a + b