在class成员函数中创建一个动态数组

Create an dynamic array in class member function

我想在我的成员函数中创建一个动态数组,但是,每次我调用该函数时似乎都会创建一个新的动态数组。无论如何要在成员函数内创建一个动态数组,这样它就不会自我改造。

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;
    }
}

以上是我的 class 和头文件,void killsRecorded(string kills) 应该会向我的数组添加 kills,但是,当我在 main.

中尝试这样做时
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

相反,Mouse 应该在第一行,Donkey 在第二行。难道我做错了什么?另外,我不能使用向量,它是用于作业的。

在您的构造函数中,为 n 分配一个默认值,例如 5。然后创建一个该大小的数组。

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

}

然后recordKills检查kills中是否有space,必要时重新分配:

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' 重命名为 'kills'。

然后在打印kills时,循环直到k:

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

    return kills;
}

记得在析构函数中删除kills!

你应该使用 std::vector... 为此,您必须

#include <vector>

使用命令

std::vector<string> kills;

您可以创建一个新的字符串向量

使用命令

kills.pushback(stringvalue);

你可以在你的向量中添加一个新字符串 "list" 你也不必计算你的杀戮...你可以使用

kills.size();

获取字符串的数量。 要取回值(字符串),您可以像数组一样使用向量

string name = kills[3];

顺便说一句:您应该将矢量保存为成员...为此,您必须将其保存在您的 class 定义中 (header)

如果你不被允许使用std::vector,你可以自己编写列表...

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;
}

嗯,你的killsRecorded(string kills)方法是编程的一个例子...

  • 你删除列表丢失了所有以前记录的杀戮
  • 你丢失了前一个 new[] 获得的指针,这会导致内存泄漏(你怎么能释放它们,现在你的程序已经忘记了分配的内容)

应该做什么(向量 class 在幕后做了什么):

  • 定义一个 您最初分配的插槽
  • 将记录的字符串添加到这个简单的数组中,直到它已满
  • 当它已满时分配另一个数组,比如两倍大小,小心地从旧数组中复制值,释放旧数组,只有它们影响新数组到保存的指针
  • 不要忘记在class析构函数
  • 中释放分配的数组
  • 并在 class 中存储当前大小(击杀数)和最大大小(分配大小)

代码可以是:

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;
}