оператор не разрешается в операторную функцию с ++ - PullRequest
0 голосов
/ 13 марта 2012

Я делал некоторую работу с классами, которым нужно перегружать некоторые их операторы (=, ==, +,! = И т. Д.) Я пишу операторные функции, но иногда они не вызываются, или компилятордействует так, как будто его даже не существует.например:

class Thing{
public:
    Thing& operator=(const Thing& _other){
        // implementation 
    }
    bool operator==(const Thing& _other){
        // implementation
    }
    Thing& operator+(const Thing& _other){
        // implementation 
    }
};

это включает в себя другие функции-члены класса (конструктор (по умолчанию), конструктор (копирование), деструктор и т. д.), но иногда метод игнорируется.

void Foo(Thing & thing1, Thing & thing2){
    //snip
    if(thing1 == thing2){
        //do some stuff
    }
    //snip
    Thing tempThing();
    thing1 = thing2 + &tempThing;
    //snip
}

в Visual-Studio я иду на компиляцию, и он считает, что нет никакого оператора, который принимает левый аргумент Thing, а затем, если я указываю thing2->operator+(&tempThing);, тогда он работает, это сбивает с толку, потому что он должен разрешить этот операторфункция только благодаря разрешению языка

, если существует функция Class operator#(Class), и аргументы могут быть преобразованы в соответствующие типы, тогда все, что нужно, это использовать оператор, и компилятор заменит его наоператор-функция или, по крайней мере, вызов операторной функции.

thing1 = thing2 + thing3;   // written line 
thing1.operator=(thing2.operator+(thing3));

зачем мне указывать оператор-функцию.не должен ли компилятор сделать это для меня.

РЕДАКТИРОВАТЬ: это вопрос общего поведения, а не фактической правильности кода.даже когда я пишу операторы, так как они должны по какой-то причине указывать фактический оператор () вместо возможности использовать символ.(Я должен был сделать это с прямыми примерами, а также скопированным символом для персонажа, но иногда это работает)

Ответы [ 3 ]

4 голосов
/ 13 марта 2012
Thing tempThing();

Это не то, что вы, вероятно, думаете. Google для "Самый неприятный анализ".

thing1 = thing2 + &tempThing;

Поскольку ваш operator+ принимает ссылки (не указатели), вы не хотите брать адрес. Как только вы исправите предыдущее определение, оно должно скомпилироваться как thing1 = thing2 + tempThing;.

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

2 голосов
/ 13 марта 2012

Обычный стиль - иметь operator+, operator- и т. Д. ... вне вашего класса или в качестве функций-друзей вашего класса и operator+=, operator-=, ... в качестве функций-членов,Это связано с тем, что последние изменяют сам объект, а первые работают с двумя объектами и возвращают третий.Вот пример кода для строкового класса, который может выглядеть следующим образом:

class string {
public:
        string& operator+=(const string& other)
        {
                this->append(other);
                return *this;
        }
private:
        void append(const string& other)
        {
                // concatenate two strings here
        }
};

string operator+(const string& first, const string& second)
{
        string result(first);
        result += second;
        return result;
}

В вашем случае изменение строк

Thing tempThing();  
thing1 = thing2 + &tempThing;

на

Thing tempThing;  
thing1 = thing2 + tempThing;

также должно работать.

1 голос
/ 13 марта 2012

вы добавляете указатель функции

Thing tempThing();
thing1 = thing2 + &tempThing;

Thing tempThing(); объявляет функцию, которая возвращает Thing, Thing tempThing; создает Thing

также:

operator==, operator+

должно быть const

...