2012-10-31 59 views
0

我想編碼一個二十一點遊戲。我在業餘時間自學C++,這是我第一次在任何有關編程的網站上發佈。在一個類中的向量的random_shuffle C++運行時錯誤

我一直在尋找我的問題的答案,因爲我走了,學到了很多..但這個問題已經完全讓我困惑。我擔心我正在接近完全錯誤的任務,希望你能幫助我。

我有一個卡類和一個持有52張卡片的矢量卡組。該向量是Deck類的私人成員,我擔心這是我的問題?

當我將random_shuffle行添加到我的代碼中時,它編譯得很好,但隨後控制檯窗口崩潰(Windows 7 x64,code :: blocks,C++)。我無法弄清楚我做錯了什麼。我所說的載體隨機訪問迭代器開始()和end()...

加入deck.h

#ifndef DECK_H 
#define DECK_H 

#include <vector> 

using namespace std; 

/** Card Class */ 
class Card 
{ 
public: 
/** Constructor prototypes */ 
//Card(); //default constructor 
Card(int s, int r) : suit(s), rank(r) {} 

/** GET function prototypes */ 
int getRank(); // returns card number as int 
string getSuit(); // returns the suit in a string 

private: 
int rank; 
int suit; 
} ; 

/** Deck class */ 
class Deck 
{ 
public: 
Deck(); 
vector <Card> get_deck() { return deck; }; 

private: 
vector<Card> deck; 
}; 

#endif // DECK_H 

deck.cpp

#include <iostream> 
#include <string> 
#include <vector> 
#include "deck.h" 

using namespace std; 

/** Deck ctor to initialise deck */ 
Deck::Deck() 
{ 
for(int suit = 0; suit < 4; suit++) 
{ 
    for(int rank = 0; rank < 13; rank++) 
    { 
     deck.push_back(Card(suit,rank)); 
    } 
} 

} 

/** Functions to GET rank and suit */ 
// Function to get rank as int 
int Card::getRank() 
{ 
return rank; 
} 

// Function to get suit as string 
string Card::getSuit() 
{ 
switch(suit) 
{ 
    case 0: 
    return "Diamonds"; 

    case 1: 
    return "Hearts"; 

    case 2: 
    return "Clubs"; 

    case 3: 
    return "Spades"; 

    default: 
    return "Error"; 
} 
} 

的main.cpp

#include <iostream> 
#include <algorithm> 
#include <ctime> // time() 
#include <string> 
#include <vector> 

#include "deck.h" 

using namespace std; 

int main() 
{ 

Deck mydeck; 

random_shuffle(mydeck.get_deck().begin(), mydeck.get_deck().end()); 

// Loop to iterate through deck of cards 
for(int i = 0; i<52; i++) 
{ 
    cout << mydeck.get_deck()[i].getRank() << " of " << mydeck.get_deck()[i].getSuit() << endl; 
} 

// Display size of deck 
//cout << endl << "The size of deck is: " << mydeck.get_deck().size() << endl; 


return 0; 
} 

任何幫助或智慧的話我將非常感激,我希望我格式化的一切權利......

非常感謝

+2

+1用於發佈可重現問題的編譯代碼,-1用於不縮小問題範圍。所以0. –

+0

你的Deck類只是一個卡片向量的[無用]包裝。在我看來,一個Deck類應該有它自己的shuffle方法,即'void Deck :: Shuffle(){random_shuffle(deck.begin(),deck.end()); '' - 以及其他方法,例如獲得頂牌或底牌,或者從牌組中獲得一張隨機牌。然後我會擺脫你的'get_deck()'方法。 –

+2

@StarPilot這是此頁面的鏈接。 – Gorpik

回答

6

這種訪問方法:

vector <Card> get_deck() { return deck; }; 

返回卡載體的副本。所以當你調用它兩次時,你會得到兩個不同的副本,第一個副本的begin()與第二個副本的end()不匹配,所以它崩潰了。

vector <Card>& get_deck() { return deck; } // no semicolon needed here 
//   ^
//   | 
// this is a reference 

然而,這允許呼叫者修改內部陣列,這通常是一個壞主意:

爲了解決這個問題,你應該參考使副本不是由返回數組。爲了避免這種情況,你應該const參考返回它:

const vector <Card>& get_deck() { return deck; } 

但是,如果你這樣做,那麼std::random_shuffle不能修改陣列。所以要解決這個問題,理想的解決方案是將類方法添加到Deck類中,該類自己調用random_shuffle

+2

random_shuffle不會與const_iterators一起使用。 – jarmond

+5

另一種選擇是在Deck類中實現shuffle。 – Will

+0

@願意這是一個更好的主意。 – jarmond

2

嘗試從get_deck()返回vector<Card>&。在發佈的代碼中,您正在製作兩個單獨的副本並返回這些副本。

random_shuffle試圖完成它的工作時,它有迭代器指向兩個不同的向量。

由於@Will在評論另一個答案指出,你會過得更好通過實施方法void Deck::shuffle()該成員deck上呼籲random_shuffle而不是暴露deck都保持封裝。

+0

我怎麼可以通過實際的卡片向外循環,而不是向量的副本?我想這是與Deck的成員函數像'void Deck :: displayCard()',然後將訪問私有變量(矢量卡組)? –