在一个类中的向量的random_shuffle C++运行时错误

问题描述:

我想编码一个二十一点游戏。我在业余时间自学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

这种访问方法:

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

尝试从get_deck()返回vector<Card>&。在发布的代码中,您正在制作两个单独的副本并返回这些副本。

random_shuffle试图完成它的工作时,它有迭代器指向两个不同的向量。

由于@Will在评论另一个答案指出,你会过得更好通过实施方法void Deck::shuffle()该成员deck上呼吁random_shuffle而不是暴露deck都保持封装。

+0

我怎么可以通过实际的卡片向外循环,而不是向量的副本?我想这是与Deck的成员函数像'void Deck :: displayCard()',然后将访问私有变量(矢量卡组)? –