我正在编写一个我要绘制卡片的程序,然后删除它以便不再绘制它。
我有一个卡片向量(包含两个定义套装和值的结构的类),名为deck,我真的不知道如何使用迭代器,这里是一段代码片段:
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"
我真的不知道该怎么做,希望有人可以帮助我,提前谢谢!
答案 0 :(得分:1)
让我先谈谈话题。你的设计有点怀疑。首先按价值传递CardDeck几乎肯定不是你想要的,但这甚至不是重点。为什么你的Player类拥有关于CardDeck私有内部的所有内部知识。你应该不关心你将牌组存储为矢量或者deque(哈哈),或者结构是什么。它应该不知道。它只知道它想丢弃一张卡片。
masterDeck.Discard(selectedCard);
另请注意,selectedCard必须介于0到 ONE LESS 之间,但是即使这可能不是你的问题(尽管它将是1/53的时间)
所以为了回答你的问题,我们现在需要更多关于masterDeck的内容。您是否实现了有效的自定义复制构造函数?由于你通过值传递赔率很好,你没有正确复制底层矢量,事实上它可能是空的,没有任何删除工作。尝试检查大小。如果您不想复制该套牌,那么您可以让编译器通过声明私有拷贝构造函数然后从不定义它来帮助您。参见Scott Meyer的Effective C ++ Item 11.
最后一条建议,我相信一旦你用你的迭代器擦除它,你就会失效。 向量可能会被重新分配(几乎可以肯定,如果你擦除除了结尾之外的任何地方)。我只是告诉你,你不要试图在同一个迭代器上多次调用erase。关于迭代器的一个棘手问题是使它们无效是多么容易,这就是为什么你经常看到它的检查!= coll.end()。
答案 1 :(得分:1)
我敢打赌getDeck
按值返回向量。它会导致itr
指向并erase
对矢量的不同副本进行操作。因此,你得到错误。您应该通过引用返回向量。将getDeck
签名更改为此签名:
vector<Card>& getDeck()
答案 2 :(得分:0)
“它是在0的边界和甲板的大小内随机生成的。”
有效范围应为“介于0和甲板大小减1”之间。这可能会在运行时生成范围错误。