删除向量中间的用户定义元素
我正在编写一个程序,我想在其中绘制一张卡片,然后删除它,以便它不会再次绘制。
我有一个卡片向量(包含 2 个定义套装和值的结构的类),称为套牌,我真的不知道如何很好地使用迭代器,这里有一个代码片段:
void Player::discardCard(CardDeck masterDeck)
{
cout << "Erasing: " << masterDeck.getDeck().at(cardSelect).toString() << endl;
/*Attempt1*/
masterDeck.getDeck().erase(masterDeck.getDeck().begin()+cardSelect);
/*Attempt 2*/
vector<Card>::iterator itr;
itr = masterDeck.getDeck().begin() + cardSelect;
masterDeck.getDeck().erase(itr);
}
cardSelect 具有我要访问的卡片的位置删除。 它是在0和牌组大小的范围内随机生成的;因此它不应该指向超出边界的位置。
每次编译时都会出现以下错误:
"Expression: vector erase iterator outside range"
我真的不知道该怎么办,希望有人可以帮助我,提前感谢!
I'm coding a program where I want to draw a card, and then delete so that it doesn't get drawn again.
I have a vector of Cards (class containing 2 structs that define Suit and Value) called deck and I don't really know how to use iterators very well, here a code snippet:
void Player::discardCard(CardDeck masterDeck)
{
cout << "Erasing: " << masterDeck.getDeck().at(cardSelect).toString() << endl;
/*Attempt1*/
masterDeck.getDeck().erase(masterDeck.getDeck().begin()+cardSelect);
/*Attempt 2*/
vector<Card>::iterator itr;
itr = masterDeck.getDeck().begin() + cardSelect;
masterDeck.getDeck().erase(itr);
}
cardSelect has the location of the card I'm going to delete.
It's generated randomly within the boundaries of 0 and the size of deck; therefore it shouldn't be pointing to a position out of boundaries.
Everytime I compile I get the following error:
"Expression: vector erase iterator outside range"
I really don't know what to do, hopefully someonw can help me, thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我敢打赌,
getDeck
按值返回向量。它导致itr
指向并erase
对向量的不同副本进行操作。因此你会得到错误。您应该通过引用返回向量。将getDeck
签名更改为此:My bet is that
getDeck
returns the vector by value. It causesitr
to point to anderase
to operate on different copies of the vector. Thus you get the error. You should return the vector by reference. ChangegetDeck
signature to this one:我先岔开话题。你的设计有点可疑。首先按值传递 CardDeck 几乎肯定不是您想要的,但这甚至不是重点。为什么您的 Player 类应该拥有有关 CardDeck 私有内部结构的所有内部知识。它不应该关心你将牌组存储为向量或双端队列(哈哈),或者结构是什么。它只是不应该知道这一点。它只知道它想弃掉一张牌。
masterDeck.Discard(selectedCard);
另请注意,selectedCard 必须在 0 到 ONE LESS 之间,而不是牌组的大小,但即使这样也可能不是您的问题(尽管这将是 1/53 的时间)
所以回答您的问题我们现在确实需要更多地了解 masterDeck。您是否实现了有效的自定义复制构造函数?由于您按值传递的可能性很大,因此您没有正确复制底层向量,事实上它可能是空的,并且任何删除都不起作用。尝试检查尺寸。如果您不想复制牌组,那么您可以让编译器通过声明私有复制构造函数然后从不定义它来帮助您。请参阅 Scott Meyer 的《Effective C++ Item 11》。
最后一条建议是,我相信一旦用迭代器擦除,它就会失效。
向量可能会被重新分配(如果你擦除除末尾以外的任何地方,几乎肯定会发生)。我只是告诉你,这样你就不会尝试在同一个迭代器上多次调用擦除。关于迭代器的棘手问题之一是使它们无效是多么容易,这就是为什么您经常看到对 iter != coll.end() 的检查。Let me go off topic first. Your design is a little suspect. First passing in CardDeck by value is almost certainly not what you want but that's even beside the point. Why should your Player class have all this inside knowledge about the private innards of CardDeck. It shouldn't care that you store the deck as a vector or deque (ha ha), or what the structure is. It just shouldn't know that. All it knows is it wants to discard a card.
masterDeck.Discard(selectedCard);
Also note that selectedCard has to be between 0 and ONE LESS than the size of the deck, but even that's probably not your problem (although it will be 1/53rd of the time)
So to answer your question we really would need to now a little more about masterDeck. Did you implement a valid custom copy constructor? Since you're passing by value odds are good you're not correctly copying the underlying vector, in fact it's probably empty and none of the deletes will work. Try checking the size. If you don't ever want the deck copied then you can let the compiler help you by declaring a private copy constructor and then never defining it. See Scott Meyer's Effective C++ Item 11.
Finally one last piece of advice, I believe once you erase with your iterator, you invalidate it.
The vector might get reallocated (almost certainly will if you erase anywhere but the end).I'm just telling you so that you don't try to call erase more than once on the same iterator. One of the tricky things about iterators is how easy it can be to invalidate them, which is why you often seen checks for iter != coll.end().“它是在 0 和牌组大小的范围内随机生成的”。
有效范围应为“0 到牌组大小减 1 之间”。这可能会在运行时产生范围错误。
"It's generated randomly within the boundaries of 0 and the size of deck".
The valid range should be "between 0 and the size of the deck minus 1". This could generate range error at run time.