Перегруженный оператор пытается принять другой перегруженный оператор в качестве параметра - PullRequest
2 голосов
/ 03 декабря 2011

У меня есть классы Pile, которые представляют колоду карт и содержат экземпляры классов Card.Я перегружен двумя операторами, Pile :: operator + = и Pile :: operator -.

int main()
{
Pile pile1(false); //construct an empty pile/deck
Pile pile2(true);  //construct a full deck with all 52 cards
output(pile1,pile2); //just a little procedure to print both decks

pile1 += --pile2;
output(pile1,pile2);
    ...

Operator + = берет другой Pile в качестве ссылки и перемещает каждую карту из параметра Pile в * this.Оператор - берет верхнюю карту из колоды и возвращает кучу, содержащую эту карту.

Что дает мне g ++, это ошибка времени компиляции, сообщающая

error: no match for 'operator+=' in 'pile1 += Pile::operator--()()'
note: candidate is: void Pile::operator+=(Pile&)

Ниже приведены перегруженныеоператоры:

void Pile::operator+=(Pile &other)
{
    Node *n = other.listHead;

        //add each card from other to *this
    while((n = n->getNext()) != NULL)
    {
        this->newCardToList(other.drawCard());
    }
}

Pile Pile::operator--()
{
    Pile pile(false);
    pile.newCardToList(this->drawCard());
    return pile;
}

Мне кажется, что оператор + = пытается принять - в качестве параметра.Я попробовал Pill1 + = (--pile2);но это ничего не изменило.

То, что я хочу (или должен сделать здесь), это взять верхнюю карту из стопки 2 и положить ее в стопку 1.Не могли бы вы подсказать, что здесь не так, поскольку я ничего не смог придумать?

Редактировать: + = требуется для изменения обоих объектов здесь.Это необходимо, потому что человек, который дал нам этот проект упражнения на нашем курсе, требует, чтобы мы делали это таким образом.Хотя его дизайн был действительно плохим, поэтому я не удивлюсь, если бы это решение было даже невозможно.

Ответы [ 4 ]

1 голос
/ 03 декабря 2011

Ваша подпись и поведение для operator+= неверны.Арифметические операторы работают по значению, как и ваши перегрузки.Наличие мутации +=, безусловно, является одним из случаев злоупотребления перегрузкой операторов.

По описанию, здесь происходит смешение идентичности объекта и идентичности значения.Вместо того, чтобы перемещать объект какого-либо типа из одного хранилища в другое, мыслить в терминах значений часто проще, лучше реализовать и более естественно в языке, подобном C ++.

0 голосов
/ 03 декабря 2011

Очевидно, что этот дизайн не работает. Могу ли я предложить превосходный дизайн:

#include <list>
struct Card {};

class Pile
{
    std::list<Card> cards;
public:
    void operator>> (Pile& other)
    {
        other.cards.splice(other.cards.end(), cards);
    }

    Pile operator--(int)
    {
        Pile result;
        result.cards.push_back(cards.back());
        cards.pop_back();
        return result;
    }
};

int main()
{
    Pile a, b;
    a-->>b;    //look how elegantly this expresses: take top card from a and append it to b
}
0 голосов
/ 03 декабря 2011

Проблема в том, что operator-- возвращает временный объект, который не может быть привязан к неконстантной ссылке в параметре operator=:

void operator+=(Pile &other) //your code

, который должен быть объявлен как:

Pile & operator+=(const Pile &other) //solution

и напишите return *this в реализации этой функции.

0 голосов
/ 03 декабря 2011

operator + = не распознается, потому что operator + = правильная подпись:

Pile operator+=(const Pile &other)

Если вы хотите изменить other внутри, вы можете использовать

Pile& mutable_other = const_cast<Pile&>(other); 

и

Node *n = mutable_other.listHead;

//add each card from other to *this
while((n = n->getNext()) != NULL)
{
    this->newCardToList(other.drawCard());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...