Как назначить операцию комплексному номеру при объявлении? - PullRequest
2 голосов
/ 14 июня 2019

Я пишу класс для комплексных чисел, и когда я объявляю одно из них, я должен объявить его до и только после того, как я могу назначить ему операцию.


Например:

Это работает :

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

Ответы [ 3 ]

5 голосов
/ 14 июня 2019

= в объявлениях не является присваиванием.

ComplexNumber a = b + c;

- это просто еще один способ записи

ComplexNumber a(b + c);

Т.е. он инициализирует a из b + c, вызываяконструктор копирования.

Ваш конструктор копирования объявлен как

    ComplexNumber(ComplexNumber &NewComplexNumber);

Он принимает свой аргумент по ссылке.Ссылки не могут привязываться к временным значениям, таким как результат выражений (например, a + b, a - b).

Исправление:

    ComplexNumber(const ComplexNumber &NewComplexNumber);

Как правило, копияконструктор всегда должен принимать аргумент по константной ссылке.

5 голосов
/ 14 июня 2019

Просто объявите конструктор копирования как

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 после списка параметров. Тот же классификатор, который нужно добавить к operator ==.

4 голосов
/ 14 июня 2019

Добавить конструктор const-копии:

ComplexNumber::ComplexNumber(const ComplexNumber & NewComplexNumber)

Строка ComplexNumber Number = a + b; вызывает конструктор копирования класса. Однако результатом a + b является r-значение, и единственный предоставленный вами конструктор копирования принимает только l-значение.

...