在一个类中的向量的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;
}
任何帮助或智慧的话我将非常感激,我希望我格式化的一切权利......
非常感谢
丹
这种访问方法:
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
。
尝试从get_deck()
返回vector<Card>&
。在发布的代码中,您正在制作两个单独的副本并返回这些副本。
当random_shuffle
试图完成它的工作时,它有迭代器指向两个不同的向量。
由于@Will在评论另一个答案指出,你会过得更好通过实施方法void Deck::shuffle()
该成员deck
上呼吁random_shuffle
而不是暴露deck
都保持封装。
我怎么可以通过实际的卡片向外循环,而不是向量的副本?我想这是与Deck的成员函数像'void Deck :: displayCard()',然后将访问私有变量(矢量卡组)? –
+1用于发布可重现问题的编译代码,-1用于不缩小问题范围。所以0. –
你的Deck类只是一个卡片向量的[无用]包装。在我看来,一个Deck类应该有它自己的shuffle方法,即'void Deck :: Shuffle(){random_shuffle(deck.begin(),deck.end()); '' - 以及其他方法,例如获得顶牌或底牌,或者从牌组中获得一张随机牌。然后我会摆脱你的'get_deck()'方法。 –
@StarPilot这是此页面的链接。 – Gorpik