2016-05-27 10 views
0

メンバー関数で動的配列を作成しようとしていますが、関数を呼び出すたびに新しい動的配列が作成されるようです。とにかくメンバ関数内で動的配列を作成して、それ自体をリメイクしませんか?クラスメンバー関数で動的配列を作成する

class predator 
{ 
private: 
    string name; 
    string species; 
protected: 
    string *list; 

public: 
    predator(string theSpecies); 
    void killsRecorded(string kills); // add a new kill to the end of the predator's list of kills 
    string *killsList(); // return a pointer to the array of all kills by this predator 
    int noOfTotalKills(); // how many kills have been recorded 

    int k; 
    static int n; 
}; 

//The header file 
void predator::killsRecorded(string kills) 
{ 
    k = 0; 
    list = new string[5]; 
    *(list + k) = kills; 
    k = n++; 
    cout<< k<< endl; 
} 

string* predator::killsList() 
{ 
    //cout<< (sizeof(list)/sizeof(list[0]))<< endl; 
    for(int i=0; i<5; i++) 
    { 
     cout<< *(list + i)<< endl; 
    } 
} 

上記は、私は私のメインの中にいることをしようとすると、ボイドkillsRecordedは(文字列は殺す)、しかし、私の配列にキルを追加する必要があり、私のクラスとヘッダファイルです。

predator *prey; 
prey = new predator("Cheetah"); 

prey->killsRecorded("Mouse"); 
prey->KillsRecorded("Donkey"); 

prey->killsList(); 

ではなく

Created a hunter that is a Cheetah 
0 
1 
Donkey 
*BLANK LINE 
*BLANK LINE 
*BLANK LINE 
*BLANK LINE 

を出力し、マウスは、第二の最初の行とロバであるべきです。私は何か間違っているのですか?また、私はベクトルを使用することはできません、それは割り当てのためです。

+2

は '文字列*李を使用していません「ベクトルリスト」を使用してください。あなたは 'n'や 'k'は必要ありません。 'cout << list [i] << endl;' – dgsomerton

+1

'recordKills'関数ではなく、コンストラクタで' list'を初期化してください。 – PcAF

+0

1.配列をメンバ変数にする2.配列をベクトルに変更 –

答えて

1

コンストラクタで、nにデフォルト値の5を指定します。次に、そのサイズの配列を作成します。

predator::predator() 
    : n(5), 
     k(0) 
{ 
    kills = new string[n]; 

} 

は、その後、必要に応じて再配分、キルにあるスペースがあるかどうかを確認するためにチェックをrecordKills:

recordKills(string kill) 
{ 
    if(k >= n) { 
     string* oldKills = kills; 
     kills = new string[2*n]; 

     // copy 
     for(int i = 0; i< n: i++) { 
      kills[i] = oldKills[i]; 
     } 

     n *= 2; 

     delete [] oldKills; 
    } 

    kills[k++] = kill; 
} 

これは、データ構造の名前で変数を呼び出すために、一般的に悪い考えですので、私は名前を変更しました'list'を 'kill'にする。キルを印刷するとき

その後、Kまでループ:

string* listKills() 
{ 
    for(int i = 0; i < k; i++) { 
     cout << kills[i] << endl; 
    } 

    return kills; 
} 

はデストラクタでキルを削除することを忘れないでください!

+0

ありがとう、これは動作します! – JohnQuestions

0

あなたが

std::vector<string> kills; 

あなたは、文字列の新しいベクトルを作成することができますコマンドを使用して

#include <vector> 

にあなたが持っていることを行うには... をのstd ::ベクトルを使用する必要があります

コマンドを使用して

kills.pushback(stringvalue); 
あなたも、あなたのキルをカウントする必要はありませんあなたのベクトル「リスト」に新しい文字列を追加することができ

...あなたが戻って文字列の数を取得するために

kills.size(); 

を使用することができます。 は、値(文字列)が戻ってあなたが

string name = kills[3]; 

ところで配列のようにベクトルを使用することができます取得するには:あなたがメンバーとしてベクトルを保存する必要があります...あなたはあなたのクラス定義でそれを保存する必要があることを行うために(ヘッダ)あなたがのstd ::ベクトルを使用することを許可arn't場合は、あなたがあなた自身のリストを書くことができ

...

class list 
{ 
private: 
    node* head;   
    int size = 0; 

    struct node 
    { 
     node* next; 
     string value; 
    } 

public: 
    list(); 
    ~list(); 
    void PushBack(string); 
    string GetElement(int index); 
    int GetSize(); 
}; 


list::list() 
{ 
    head = new list(); 
    head->next = nullptr; 
} 

list::~list() 
{ 
    node* temp = head; 
    node* temp2 = temp; 
    do //delete hole list 
    { 
     temp2 = temp->next; 
     delete temp; 
     temp = temp2; 
    }while(temp != nullptr); 
} 

void list::PushBack(string item) 
{ 
    node* temp = head; 
    while(temp->next != nullptr) 
    { 
     temp = temp->next; 
    } 
    //found the end of the list 
    node* newNode = new node(); 
    newNode->value = item; 
    newNode->next = nullptr; 
    temp->next = newNode; 
    size++; 
} 

int list::GetSize() 
{ 
    return size; 
} 

string list::GetElement(int index) 
{ 
    node* temp = head; 
    while(temp->next != nullptr) 
    { 
     temp = temp->next; 
     if(index == 0) 
     { 
      return temp->value; 
     } 
     index--; 
    } 
    //index out of bounds 
    return ""; 
} 

コードは、現時点で正しいかどう私がチェックすることはできません、このコンピュータにはIDEがないので...しかし、私はそれが言葉だと思います。ところで

):あなたが書く必要があることを行うために、配列の代わりにこのリストを使用することができます。

list kills; 

kills.PushBack("Peter"); 
kills.PushBack("Thomas"); 
kills.PushBack("Alex"); 

for(int i = 0; i< kills.GetSize();i++) 
{ 
    std::cout<<kills.GetElement(i)<<std::endl; 
} 
0

うーんを、あなたのkillsRecorded(string kills)方法はどのようにないの例ですプログラムへの ...

  • すべてが以前
  • を殺す記録しますが、メモリリーにつながり、前new[]によって得られたポインタを失う失うリストを消去(クラスはボンネットの下に何をするかベクトル)行われるべきである何のk(あなたがそれらを解放することができ、今あなたのプログラムが割り当てられていたものを忘れているか)

  • は、スロットのチャンクを定義しますそれがいっぱいになるまで、あなたは最初に
  • は、この単純な配列に記録された文字列を追加割り当てることを
  • 慎重に古い配列から値をコピーし、別の配列は、2倍のサイズで言う割り当てる古い配列を解放し、唯一のフルです
  • それらはthに影響を与える電子保存されたポインタ
  • に新しい配列がクラスで現在のサイズを、クラスのデストラクタ
  • とストア内に割り当てられた配列を解放することを忘れないでください(キル数)と最大サイズ(割り当てられたサイズ)

コードは次のようになります。

class predator 
{ 
private: 
    string name; 
    string species; 
protected: 
    string *list; 
    size_t max_size; 
    size_t cur_size; 

public: 
    predator(string theSpecies); 
    void killsRecorded(string kills); // add a new kill to the end of the predator's list of kills 
    string *killsList(); // return a pointer to the array of all kills by this predator 
    int noOfTotalKills(); // how many kills have been recorded 

    /*int k; what it that??? 
    static int n;*/ 
}; 

//実装ファイル

predator(string theSpecies): species(species) { 
    list = new string[5]; 
    max_size = 5; 
    cur_size = 0; 
    // what do you do with name ? 
} 

void predator::killsRecorded(string kills) 
{ 
    if (cur_size >= max_size) { /* need a bigger array */ 
     max_size *= 2; 
     temp = new string[max_size]; 
     for(int i=0; i<cursize; i++) { // copy previous recorded values 
      temp[i] = list[i]; 
     } 
     delete[] list; // free previous allocated array 
     list = temp;  // ok list is now big enough 
    } 
    list[cur_size++] = kills; 
} 
+0

ありがとう、これも動作します。 – JohnQuestions

関連する問題