2016-12-29 5 views
-1

クラスを使用してC++でスペースインベーダーゲームのクローンを作成しています。私は、レーザーが、このエイリアンを含むメモリーが解放され、このエイリアンの右にあるすべてのメモリーが1つ後にシフトされることを、オブジェクトの配列に格納されているエイリアンと接触すると、それを望む残りのオブジェクトを格納するより小さな一時的な配列を作成して、元のメモリを削除して一時メモリに戻すことができます。 (これは長いプロセスのように思えるかもしれませんが、ゲーム全体を通してisAliveブールをチェックする必要がなくなり、検索機能がより効率的になります)。オブジェクトの配列(オブジェクトのダイナミックメモリ割り当て)からオブジェクトを削除(メモリ解放)するには

これは私がこれまで持っているものです。

Ennemi::Ennemi() :ExtraTerrestre(0, 0) { 

    maxElements = 1; // int maxElements 
    nbElements = 0; // int nbElements 
    ptr = new Ennemi*[maxElements]; // (Ennemi **ptr) 
} 

int Ennemi::chercherElement(Ennemi element[]){ 

    int indice = 0; 
    while (indice < nbElements && ptr[indice] != element) 
     indice++; 

    // opérateur ternaire, retourne l'indice si vrai, sinon retourne -1 
    return indice < nbElements ? indice : -1; 
} 

void Ennemi::retirerEnnemi(Ennemi element[]) { 
    int indice = chercherElement(element); 

    // si un element est trouver active la condition 
    if (indice != -1) { 
     // preserver l'ordre du tableau 
     for (int i = indice; i < (nbElements - 1); i++) { 
      ptr[i] = ptr[i + 1]; 
     } 
     nbElements--; 
     maxElements = nbElements; 

     // allocation d'une zone memoire 
     double *ptrTemporaire = new double[maxElements]; 

     // copie des elements dans la nouvelle zone 
     for (int i = 0; i < nbElements; i++) { 
      ptrTemporaire[i] = ptr[i]; 
     } 
     // on libere l'ancienne zone memoire 
     delete[] ptr; 

     // fait pointer le pointeur sur la nouvelle zone 
     ptr = ptrTemporaire; 
    } 
} 

P.S.ベクトルを使用して提案しないでください、私はそれを簡単な方法ではない私の理解を改善しようとしています。

+0

私のコードに誤りがあります。 "double * ptrTemporaire = new double [maxElements];" – Kevin

+1

それは唯一のエラーではありません、あなたのコードはコンパイル可能ではなく、かなり大きな混乱です。生の配列で作業したい場合は、そのトピックをよりよく理解する必要があります。 – Slava

+0

バッファは 'Ennemi ** ptr'か' Ennemi element [] 'ですか?あなたのコードからは不明です。 –

答えて

0

私の提案は、簡単にメモリを解放してメンバを移動できるように、リンクリスト構造を作成することです。すべてのこの関数の

0

まず正常に動作しますが、それが不十分に設計されています

int Ennemi::chercherElement(Ennemi element[]); 

(私のフランス語はご容赦)この関数は、ポインタによって要素のインデックスを見つけることとしますが、あなたの関数名がfindElementで、要素の配列を渡します。構文的には同じですが、それは自分を含めて、読者を混乱させる、それは次のようになります。

int Ennemi::findElementIndex(Ennemi *element); 

(またはフランス語に戻す翻訳)は、今では完全に正しい、我々は、このメソッドはelementを変更することとしていないことに気づくべきで作ることも配列からそう

int Ennemi::findElementIndex(const Ennemi *element) const; 

内部データ、今すぐ消去データは、あなたのコードはほとんど正しいですが、オブジェクト自体を削除するコードが欠落しています

if (indice != -1) { 
     delete ptr[i]; // this missing 
     // preserver l'ordre du tableau 
     for (int i = indice; i < (nbElements - 1); i++) { 
      ptr[i] = ptr[i + 1]; 
     } 
     nbElements--; 
    } 
動的に割り当てられたデータを縮小しようとした後は、

を実行しないでください。メモリの割り当て/割り当て解除は非常にコストがかかる操作なので、十分なスペースがない場合(通常は1つではなく、一部のデルタで展開しないでください)、展開しないでください。縮む必要はありません再び。あるいは、少なくともデルタで縮むかもしれません。例えば、元素の量は、== maxElemens/2

また、この行時に:あなたはdoubleの配列を作成し、Ennemiへのポインタの配列に代入してみてください

double *ptrTemporaire = new double[maxElements]; 

が、これは間違いなく間違っています。

+0

ありがとう。うん、私は値を移動する前に問題のオブジェクトを削除することを忘れないでください。そして、あなたの権利私は漸進的にメモリを1つずつ縮小する必要はありません、ちょうどエイリアンの数を追跡して(そして検索限界を減らして)、後でデルタでメモリを縮小する方がはるかに効率的です。私は*要素(尖った部分の値)を使うことを考えましたが、なんらかの理由で頭の中でつながっていませんでした:(。 – Kevin

関連する問題