Ошибка с перегрузкой оператора C ++ - PullRequest
0 голосов
/ 20 мая 2011
#include<iostream>
using namespace std;

class complex {
    double real;
    double image;
public:
    complex(double r=0,double i=0) : real(r), image(i) { };
    complex(const complex& c) : real(c.real), image(c.image) { };
    ~complex(){};
    double re() const {
        return real;
    };
    double im() const{
        return image;
    };
    const complex& operator =(const complex&c)
    {
        real = c.real;
        image = c.image;
        return *this;
    };
    const complex& operator +=(const complex&c)
    {
        real += c.real;
        image += c.image;
        return *this;
    };
    const complex& operator -=(const complex&c)
    {
        real -= c.real;
        image -= c.image;
        return *this;
    };
    const complex& operator *=(const complex&c)
    {
        double keepreal=real;
        real = real * c.real - image * c.image;
        image = keepreal * c.image + image * c.real;
        return *this;
    };
    const complex& operator /=(double d)
    {
        real/=d;
        image/=d;
        return *this;
    };

    friend complex operator !(const complex &c)
    {
        return complex(c.re(),-c.im());
    };
    friend double abs2(const complex& c)
    {
        return (c.re() * c.re() + c.im() * c.im());
    };
    const complex& operator /=(const complex&c)
    {   
        return *this *= (!c) /= abs2(c);
    };
    const complex operator +(const complex& c, const complex& d)
    {
        return complex(c.re() + d.re(), c.im() + d.im());
    };
    const complex operator -(const complex& c, const complex& d)
    {
        return complex(c.re() - d.re(), c.im() - d.im());
    };
    const complex operator -(const complex&c)
    {
        return complex(-c.re(), -c.im());
    };
    const complex operator /(const complex& c,const complex& d)
    {
        return complex(c) /= d;
    };
};

int main() {
    complex c = 1., d(3.,4.);

    return 0;
}

ВЫХОД:

Строка 62: ошибка: 'комплексный комплекс const :: оператор + (комплексный комплекс &, комплексный констант &)' должен принимать либо ноль, либо один аргумент
компиляция прекращена из-заto -Wfatal-errors.

, пожалуйста, помогите: http://codepad.org/cOOMmqw1

Ответы [ 5 ]

10 голосов
/ 20 мая 2011

Существует две альтернативы для перегрузки бинарного оператора +, как свободной функции или как функции-члена. В качестве функции-члена подпись Type operator+( Type const & ) const (const здесь необязательна, но я предполагаю, что a+b не изменяет a, что кажется справедливым предположением).

Альтернативный подход - использование свободной функции, которая принимает два объекта и возвращает сумму. Для этого существуют разные подписи, но наиболее широко принятым будет: Type operator+( Type lhs, Type const & rhs ) (обратите внимание, что первый аргумент - по значению ), где реализация внутренне изменяет и возвращает lhs. В частности, общий подход к перегрузке арифметических операторов заключается в реализации operator+= в качестве функции-члена, а затем реализации свободной функции operator+ в терминах первого:

struct Type {
   // ...
   Type& operator+=( Type const & );
};
Type operator+( Type lhs, Type const & rhs ) {
   return lhs+=rhs;
}

Таким образом, вам не нужно предоставлять дружбу бесплатной функции. В некоторых случаях, в частности с шаблонами, иногда рекомендуется определять оператор внутри определения класса, и в этом случае вам придется сделать его friend (не для доступа, но по синтаксическим причинам:

struct Type {
   // ...
   Type& operator+=( Type const & );
   // Still a free function:
   friend Type operator+( Type lhs, Type const & rhs ) {
      return lhs+=rhs;
   }
};

По причинам использования этого шаблона ... Реализация operator+= сначала, а затем operator+ поверх него обеспечивает две отдельные операции за небольшую дополнительную плату (operator+ - это однострочная функция!). Реализация его как функции-члена (operator+= также может быть бесплатной функцией) делает его похожим на operator= (должен быть членом) и устраняет необходимость в дружбе.

Причина применения operator+ в качестве свободной функции связана с симметрией типа операции. Добавление является коммутативным (a+b == b+a), и вы ожидаете того же при использовании вашего типа. Вы предоставили неявный конструктор (ваш сложный тип может быть неявно преобразован из int благодаря конструктору complex( double r = 0, double i = 0 ), и это позволяет компилятору использовать эти преобразования, если вызов функции не полностью соответствует перегрузке.

Если operator+ реализован как функция-член, компилятору разрешается учитывать эту перегрузку только тогда, когда первый аргумент равен complex, и он неявно преобразует другой аргумент, позволяя вам ввести complex(0,0)+5. Проблема в том, что если вы измените порядок 5+complex(0,0), то компилятор не сможет преобразовать 5 в комплекс, а затем использовать элемент operator+. С другой стороны, если вы предоставите ее как свободную функцию, компилятор обнаружит, что один из двух аргументов совпадает в обоих случаях, и попытается преуспеть в преобразовании другого аргумента. Конечным результатом является то, что с помощью бесплатной функции вы разрешаете в одной реализации все эти три дополнения: complex+complex, complex+double, double+complex (и дополнительно для всех целочисленных типов и типов с плавающей запятой, поскольку они могут быть преобразованы в double

Если operator+ принять первый аргумент по значению, это означает, что компилятор может при некоторых обстоятельствах исключить копию: a + b + c связывается как (a+b) + c, временный результат первой операции может использоваться непосредственно как аргумент для второй вызов, без дополнительного копирования.

5 голосов
/ 20 мая 2011

Вы перегружаете +, /, - и * таким образом

complex operator+(const complex& c) const 

Вам нужен только один аргумент, так как левый аргумент равен this

Пример

complex operator+(const complex& c) const 
{
    return complex(c.re()+this->re(),c.im()+this->im());
};
2 голосов
/ 20 мая 2011
* Ваш 1000 *
const complex operator+(const complex& c, const complex& d)
{
return complex(c.re()+d.re(),c.im()+d.im());
};

является функцией-членом complex. Этот прототип для глобального operator+. В функции-члене c предполагается равным *this, поэтому не указывается.

Но вам действительно нужно начать правильно форматировать код, начиная с отступа. Начинающие программисты не понимают, насколько важно правильное форматирование при показе вашего кода другим.

2 голосов
/ 20 мая 2011

Оператор + должен принимать один параметр:

complex operator+(const complex& c) const
{ 
   return complex(c.re()+re(),c.im()+im());
}

Другой комплекс является текущим объектом.

1 голос
/ 20 мая 2011

Существует также другой способ перегрузки двоичного оператора, если вы действительно ищете перегрузку оператора с двумя параметрами.Тогда вы можете попробовать что-то вроде этого.

friend complex operator+(const complex& c, const complex& d)
 {
  complex r;
  r.real = c.re() + d.re();
  r.image = c.im() + d.im();
  return r;
 }
...