C ++:如何将更改应用于动态数组交叉函数?

时间:2016-01-04 22:35:27

标签: c++ arrays dynamic scope variable-assignment

我正在尝试扩展名为Coffee(Coffee * brands = new Coffee[sizeOf];)的类的动态对象数组,通常我会创建一个临时动态数组,其大小比初始数组的大小大一个 - 我复制它们到temp,在最后添加新的,删除旧的,重新创建但扩展,并从temp复制回来的所有内容。

但是现在,我必须在数组必须位于的主函数之外执行它(是的,这是一个赋值,在那个是一个棘手的函数),所以我携带数组以及作为参数的大小,并开始制作临时数组并复制所有内容,最后添加新对象。

现在这就是我失去的地方;如果我想通过子函数从main中删除数组,如何通过相同的函数替换它/重新创建它?这对我来说听起来毫无意义,但我不知道如何在需要的时候获得额外的缺口,或者只是在大小变量上添加+1并以某种方式将新对象的信息复制到最后一个插槽?

这个问题并不重复,因为我已经检查过其他问题的其他一些答案,但找不到同一个问题,因为这是关于从另一个函数中进行更改一个动态数组,我见过的每个答案(例如这个:How to expand an array dynamically in C++? {like in vector })只处理主函数,或建议向量(因为我必须使用它而对我没用动态数组),我被*(p+i) = i之类的一些不相关的细节感到困惑。

此外,有人可以解释这里的范围差异以及为什么您的解决方案与它们协调工作?我忽视或错过了什么?

一些代码:

#include <iostream>
#include <string>
#include "Coffee.h"

using namespace std;

void addCoffee(Coffee c[], int &amount);
void showAllCoffees(Coffee c[], int amount);

int main()
{
    int sizeOf = 5;
    Coffee * brand = new Coffee[sizeOf];
    addCoffee(brand, &sizeOf);
    showAllCoffees(brand, sizeOf); //nevermind this part, 
                                   //just added it so it makes more sense
    delete [] brand;
    return 0;
}

void addCoffee(Coffee c[], int &amount){
    string name;
    amount++;
    Coffee * temp = new Coffee[amount];

    for(int i=0;i<amount-1;i++){
        temp[i] = c[i];
    }

    cout<<"What is the coffee's name?: ";
    cin>>name;
    temp[amount-1].setName(name);

    /*THIS IS WHERE I'M NOT SURE WHAT TO DO*/

    delete [] temp;
}

4 个答案:

答案 0 :(得分:3)

  

我正在尝试扩展一个名为的类的动态对象数组   咖啡(咖啡*品牌=新咖啡[sizeOf];),通常我会   制作一个临时动态数组,其大小比初始大一   数组的大小 - 我将它们复制到temp,最后添加新的,   删除旧的,重新创建但扩展,然后复制回来   一切都来自临时。

  

我见过的每个答案(比如这一个:如何扩展数组   在C ++中动态? {喜欢在矢量})处理   仅提供主要功能,或向量建议(这对我没有帮助   因为我必须使用动态数组

我认为你真的需要一个std::vector

那些动态数组。

<强>更新

好的,这可能是您被迫创建自己的动态数组的任务。关于扩展和添加新项目的一个快速提示:

通常通过重新分配/增长现有数组来完成扩展(但这可能在此分配之外)。但是如果通过每次创建一个新数组进行扩展,最好以更大的大小增加数组(并跟踪分配的大小)。这样您就不必为每个add()创建一个新的。

通常这是通过扩大2:16项的权力大小来实现的 - &gt; 32 - &gt; 64 - &gt; 1024,从那时起每次1024.

因此,最好创建自己的动态数组类(您可以在其中跟踪分配的大小,项目数等)。

编辑:查看Jerry Coffin's blog post以获得一个很好的例子。

答案 1 :(得分:3)

您必须将引用传递给指向函数的指针:

void addCoffee(Coffee *&c, int &amount){
                   // ^^ c is input and output
    string name;
    amount++;
    Coffee * temp = new Coffee[amount];

    for(int i=0;i<amount-1;i++){
        temp[i] = c[i];
    }

    cout<<"What is the coffee's name?: ";
    cin>>name;
    temp[amount-1].setName(name);

    delete [] c; // delete old array
    c = temp;    // assign new array pointer to c
}

但我建议使用std::vector代替动态数组。

void addCoffee( std::vector<Coffee> &c ){

    cout<<"What is the coffee's name?: ";
    cin>>name;
    c.push_back( Coffee( name ) );
}

答案 2 :(得分:2)

您将指针传递给addCoffee。由于您希望能够修改该指针,因此您可能希望通过引用而不是值传递它。

void addCoffee(Coffee *&c, int &amount)

然后在addCoffee内部,在您将所有元素从c复制到temp(并将新项目添加到temp)之后,想要交换指针tempc,然后删除旧数组。

如果我在这个一般订单上做了什么,我可能会定义一个结构来保存指针和当前大小:

template <class T>
struct dynamic_array {
    T *array;
    size_t size;
};

这几乎向std::vector提供了一小步。

答案 3 :(得分:0)

addCoffee结束时,请勿delete[] temp - 这是您的新数据的存储位置;而是delete[] c,然后是return temp,并将函数返回类型更改为Coffee* 主要说brand = addCoffee(...)所以它保存了返回值。

所有这一切,你已经有了一些想法 - 尽管前5个元素中没有数据,你仍然坚持初始大小为5。