重载运算符试图将另一个重载运算符作为参数

Overloaded operator trying to take another overloaded operator as parameter

本文关键字:重载 运算符 参数 另一个      更新时间:2023-10-16

我有类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+=将另一张牌作为参考,并将每张牌从参数"牌堆"移动到*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;
}

在我看来,运算符+=正试图将--作为参数。我试过pile1+=(--pile2(;但这并没有改变任何事情。

我想(或需要在这里做(的是从pile2中取出最上面的牌并将其放入pile1。你能告诉我这里出了什么问题吗,因为我什么都没想出来?

编辑:在此处修改两个对象都需要+=。这是必要的,因为在我们的课程中给我们这个练习项目的人要求我们这样做。不过,他的设计真的很糟糕,所以如果这个解决方案不可能实现,我也不会感到惊讶。

operator+=的签名和行为是错误的。算术运算符按值工作,重载也是如此。有一个突变的+=肯定是运算符重载被滥用的情况之一。

通过描述,这里发生的是对象身份和价值身份的混淆。在像C++这样的语言中,从值的角度思考通常更容易、实现更好、更自然,而不是将某种类型的对象从一个存储移到另一个存储。

运算符++无法识别,因为运算符++正确的签名是:

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

问题是operator--返回一个临时对象,该对象无法绑定到operator=:参数中的非常量引用

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

应声明为:

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

并在该功能的实现中写入CCD_ 6。

显然这种设计不起作用。我可以推荐一种更高级的设计吗:

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