5

カードを描画したいプログラムをコーディングしてから、カードが再度描画されないように削除します。

私はdeckと呼ばれるカードのベクトル(SuitとValueを定義する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"

私は本当に何をすべきかわかりません、うまくいけば、誰かが私を助けてくれることを願っています、事前に感謝します!

4

3 に答える 3

1

最初にトピックから外します。あなたのデザインは少し疑わしいです。CardDeckを最初に値で渡すことは、ほぼ確実にあなたが望むものではありませんが、それは重要ではありません。なぜあなたのPlayerクラスはCardDeckのプライベートな内部についてのこれらすべての内部知識を持っている必要があります。デッキをベクトルまたは両端キュー(ハハ)として保存すること、または構造が何であるかを気にする必要はありません。それを知らないはずです。それが知っているのは、カードを捨てたいということだけです。

masterDeck.Discard(selectedCard);

また、selectedCardはデッキのサイズよりも0から1小さい必要がありますが、それでもおそらく問題ではないことに注意してください(ただし、1/53の時間になります)

したがって、あなたの質問に答えるには、masterDeckについてもう少し詳しく説明する必要があります。有効なカスタムコピーコンストラクターを実装しましたか?値のオッズを渡すのは良いことなので、基になるベクトルを正しくコピーしていません。実際、それはおそらく空であり、削除は機能しません。サイズを確認してみてください。デッキをコピーしたくない場合は、プライベートコピーコンストラクターを宣言し、それを定義しないことで、コンパイラーに支援を求めることができます。ScottMeyerの効果的なC++アイテム11を参照してください。

最後にもう1つアドバイスがあります。イテレータで消去すると、無効になると思います。ベクトルは再割り当てされる可能性があります(最後以外の場所で消去すると、ほぼ確実に再割り当てされます)。同じイテレータでeraseを2回以上呼び出そうとしないように言っているだけです。イテレータのトリッキーな点の1つは、イテレータを無効にするのがいかに簡単かということです。そのため、イテレータのチェックがよく見られます!= coll.end()。

于 2011-04-01T06:01:09.540 に答える
1

私の賭けは、getDeck値によってベクトルを返すことです。これにより、ベクトルのさまざまなコピーをitrポイントして操作します。eraseしたがって、エラーが発生します。参照によりベクトルを返す必要があります。getDeck署名を次のように変更します。

vector<Card>& getDeck()
于 2011-04-01T06:08:58.253 に答える
0

「0とデッキのサイズの境界内でランダムに生成されます」。

有効な範囲は、「0からデッキのサイズから1を引いた値の間」である必要があります。これにより、実行時に範囲エラーが発生する可能性があります。

于 2011-04-01T06:05:29.267 に答える