我试图在矢量中将这些卡片洗牌

时间:2017-05-31 01:51:18

标签: c++

        int main() {

        std::vector<Card> listOfCards; 



         for (int j = 0; j < 52; j++) {
            Card card(j / 13, j % 13);
            listOfCards.push_back(card);
        }


        std::random_shuffle(listOfCards.begin(),listOfCards.end());

        for(int i = 0; i < listOfCards.size(); i++)
            std::cout << listOfCards[i].display() << std::endl;

我得到的结果与向量中的结果相同。我尝试使用Integers随机shuffle工作正常。当我洗牌非原始物体时,我还需要什么特别的东西吗?

    This is my Card class

         class Card{
          private:
          int suit,rank,value;
          public:
        Card();
        Card(int suit,int rank, int value);
        Card(int suit,int rank);

显示方法

  std::string Card::display(){
  std::string suits[] = {"Club","Spade","Heart","Diamond"};
  std::string ranks[] =   
                  {"Ace","2","3","4","5","6","7","8","9","10","Jack","Queen","King"};
                   return suits[this->suit] + "\t" + ranks[this->rank];}

类的构造函数

          Card::Card(int suit, int rank) {
               this->suit = suit;
               this->rank = rank;
               this->value = 0;

        }

这是我的两个操作符重载函数。它们是否正确实现?

    Card &Card::operator=(const Card &card) {
        Card myCard;
        myCard.suit = card.suit;
        myCard.value = card.value;
        myCard.rank = card.rank;
        return myCard;
    }

bool Card::operator<(const Card card) {
    return this->getRank() < card.getRank();
}

1 个答案:

答案 0 :(得分:0)

分配运算符未正确实现。在这种情况下,如果你摆脱了定义,代码将正常工作,但我会解释它的错误,以备将来参考。

赋值运算符的返回值通常是对刚刚赋给的对象副本的引用(因此,如果你写x =(A = B),x将是对一个新对象的引用)赋值后A的值,A,B和x将是三个不同的对象,它们都具有相同的值)。通常不使用返回值。

如果编写自己的复制赋值运算符,只要它具有正确的类型,就可以使它返回所需的任何对象。但是,等号左侧的对象不会采用返回对象的值。

因此,为了解释您的复制赋值运算符正在做什么,让我们看看会发生什么:

Card &Card::operator=(const Card &card) {
    Card myCard;
    myCard.suit = card.suit;
    myCard.value = card.value;
    myCard.rank = card.rank;
    return myCard;
}

它接受一个名为card的Card引用对象。它创建了一个名为myCard的Card类型的局部变量。然后,它将每个数据成员从输入卡复制到本地变量myCard。然后它通过引用返回局部变量。所以,如果我们有

Card A(1,1);
Card B(2,2);
Card x(3,3);
x = (A=B);

在最后一行中,在括号中,使用参数B调用A的赋值运算符。在此内部,创建局部变量并给出值(2,2)。返回并传递给x的赋值运算符。在那里创建一个局部变量并赋值(2,2),然后在不使用时销毁它。最后,没有任何改变。

您需要做的是:

Card &Card::operator=(const Card &card) {
    suit = card.suit;
    value = card.value;
    rank = card.rank;
    return *this;
}

这里,在函数内部,变量suit指的是调用赋值运算符的对象的“suit”成员,它是等号左侧的对象。所以,如果你写

A=B

然后,调用A的赋值运算符,并修改A.suit值。

另外,让我们看看你的构造函数:

Card::Card(int suit, int rank) {
           this->suit = suit;
           this->rank = rank;
           this->value = 0;

    }

写这个的更标准的方法是这样的:

Card::Card(int _suit, int _rank) {
           suit = _suit;
           rank = _rank;
           value = 0;

    }

或:

Card::Card(int _suit, int _rank) : suit(_suit), rank(_rank), value(0)
{}

因此,您可以按名称区分参数和数据成员。行为将是相同的,但这更清晰,更短。