C++ 如何在声明期间将操作分配给复数?

C++ 如何在声明期间将操作分配给复数?,c++,reference,operator-overloading,copy-constructor,complex-numbers,C++,Reference,Operator Overloading,Copy Constructor,Complex Numbers,我正在为复数编写一个类,当我声明其中一个时,我必须在之前声明它,并且只有在我可以为它分配一个操作之后才能声明它 例如: 这是有效的: ComplexNumber Number; Number = AnotherComplex + (or -) AgainAnotherComplex; ComplexNumber Number = AnotherComplex + (or -) AgainAnotherComplex; 这不起作用: ComplexNumber Number;

我正在为复数编写一个类,当我声明其中一个时,我必须在之前声明它,并且只有在我可以为它分配一个操作之后才能声明它


例如:

这是有效的

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

这不起作用

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
#如果包含复数
#定义包含的复数
#包含//用于std名称空间
类复合数
{
公众:
ComplexNumber();
复数(浮点实部、浮点虚部);
ComplexNumber(ComplexNumber和NewComplexNumber);
~ComplexNumber();
void SetRealPart(float RealPart);
无效设置图像部分(浮动图像部分);
友元复数运算符+(常数复数复数复数复数1,常数复数复数复数复数2);
友元复数运算符-(常数复数复数复数复数复数1,常数复数复数复数复数2);
friend std::ostream&operator(std::istream&input,ComplexNumber&NumberInput);
布尔运算符==(常数复数复数);
布尔运算符!=(常数复数复数);
私人:
浮动实部;
漂浮想象部分;
};
#endif//包含复数
我还将.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;
}
#包括“复数.h”
ComplexNumber::ComplexNumber()
{
RealPart=0;
想象部分=0;
}
ComplexNumber::ComplexNumber(float RealPart、float ImaginaryPart)
{
SetRealPart(RealPart);
设置图像部分(图像部分);
}
ComplexNumber::~ComplexNumber()
{
}
ComplexNumber::ComplexNumber(ComplexNumber和NewComplexNumber)
{
RealPart=NewComplexNumber.RealPart;
ImaginaryPart=number.ImaginaryPart;
}
void ComplexNumber::SetRealPart(float RealPart)
{
此->RealPart=RealPart;
}
void ComplexNumber::SetImageAryPart(浮点ImageAryPart)
{
此->图像部分=图像部分;
}
ComplexNumber运算符+(常量ComplexNumber Complex1,常量ComplexNumber Complex2)
{
ComplexNumber临时ComplexNumber;
临时complexnumber.RealPart=Complex1.RealPart+Complex2.RealPart;
临时复合体number.ImaginaryPart=Complex1.ImaginaryPart+Complex2.ImaginaryPart;
返回临时复数;
}
ComplexNumber运算符-(常量ComplexNumber Complex1,常量ComplexNumber Complex2)
{
ComplexNumber临时ComplexNumber;
临时complexnumber.RealPart=Complex1.RealPart-Complex2.RealPart;
TemporaryComplexNumber.ImaginaryPart=Complex1.ImaginaryPart-Complex2.ImaginaryPart;
返回临时复数;
}

std::ostream&operator只需声明复制构造函数

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 );
}

注意参数列表后的限定符
const
。声明中的
=
运算符==

中需要添加的同一限定符不是赋值

ComplexNumber a = b + c;
这只是另一种写作方式

ComplexNumber a(b + c);
也就是说,它通过调用复制构造函数从
b+c
初始化
a

您的副本构造函数声明为

    ComplexNumber(ComplexNumber &NewComplexNumber);
它引用它的论点。引用不能绑定到临时值,例如表达式的结果(例如
a+b
a-b

修正:


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

添加常量复制构造函数:

ComplexNumber::ComplexNumber(const ComplexNumber&NewComplexNumber)


ComplexNumber=a+b调用类的复制构造函数。但是,
a+b
的结果是一个r值,您提供的唯一复制构造函数只接受一个l值。

注意:您可以使用
std::complex
<代码>这不起作用:
-如何检测“不起作用”状态?它编译吗?有什么警告吗?错误?它会引发异常吗?结果与你期望的不同?很可能您缺少
ComplexNumber(const ComplexNumber&NewComplexNumber)构造函数。你的头文件名(
“Complex Numbers.h”
)中真的有空格吗?
const
在copy-ctor中丢失,默认的一个将完成这项工作。我添加了const关键字,现在它可以工作了,谢谢@KamilCukA更方便地实现
操作符=
返回!(*这=复杂)
。我很少看到
友元ComplexNumber操作符+(const ComplexNumber&Complex1,const ComplexNumber&Complex2)在类中用作成员。更普遍的是
ComplexNumber操作符+(const ComplexNumber&complex2)const。我想知道使用前者是否有什么好处,即友好运算符+?@TrebledJ通常将二进制运算符声明为友好函数,以允许隐式转换。啊,这太好了。很高兴知道。:-)