2017-05-31 16 views
-6
 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ランダムシャッフルでうまく動作しようとしました。私はプリミティブ以外のオブジェクトをシャッフルするときに何か特別なものが必要ですか?クラスのこれらのカードをベクトルでシャッフルしようとしています

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; 

     } 

これは、彼らが正しく実装私の2つの演算子のオーバーロードのfunctions.Areのですか?

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

カードはどのように宣言されていますか?あなたはここに投稿できますか? – Zakir

+0

*「プリミティブではないオブジェクトをシャッフルするときは何か特別なものが必要ですか?」*いいえ、そうではありません。あなたの間違いは他の場所にあります。質問を編集して[mcve]を提供してください。 –

+0

注意: 'std :: random_shuffle'はC++ 14では廃止され、C++では削除されます17。 –

答えて

0

割り当て演算子が正しく実装されていません。この場合、定義を削除すればコードはうまく動作しますが、将来の参考のために何が問題なのかを説明します。

代入演算子の戻り値は、通常、割り当てられたオブジェクトのコピーへの参照です(したがって、x =(A = B)と書くと、xは新しいオブジェクトへの参照になります)。代入後にAの値を持ち、A、B、およびxはすべて同じ値を持つ3つの異なるオブジェクトになります)。戻り値はしばしば使用されません。

独自のコピー代入演算子を記述すると、適切な型のオブジェクトを返すことができます。ただし、等号の左側のオブジェクトは、返されたオブジェクトの値をとらない。だから、

、のは、何が起こるか見てみましょう、あなたのコピー代入演算子が何をしているかを説明する:

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

それはカードと呼ばれるカードの参照オブジェクトになります。 myCardという名前のCard型のローカル変数を作成します。次に、各データメンバーを入力カードからローカル変数myCardにコピーします。次に、参照によってローカル変数を返します。この引数B.内部で呼び出されるAの代入演算子を括弧内に、我々は、最後の行では

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

を持っているのであれば、ローカル変数が作成され、値(2,2)を与えています。これは返され、xの代入演算子に渡されます。ローカル変数がそこに作成され、(2,2)の値が割り当てられ、使用されないときに破棄されます。結局、何も変わりません。あなたがする必要がどのような

はこれです:

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

、関数内で、変数スーツは上のオブジェクトです代入演算子と呼ばれているオブジェクトの「スーツ」メンバーを指し、等号の左側。したがって、書いた場合

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) 
{} 

ですから、引数とデータメンバーを名前で区別することができます。行動は同じですが、これはより明確で短くなります。

関連する問題