可变长度的类数组

时间:2009-09-21 14:35:14

标签: c++

我有一些有效的代码:

class dummie_type
{
    public:
    int a;

    void do_stuff()
    {
        // blah
    }
};

class dummie_type dummie[10];

void main()
{
    subroutine();
}

void subroutine()
{
    dummie[3].a = 27; // etc...
    dummie[5].do_stuff();
}

请注意,类的数组是全局的,我需要它保持这样(这是一个很长的故事)。 我需要更改此代码,以便类的数组具有可变长度。我知道这将涉及制作一个全局指针,然后将其设置为指向在main中获得malloc或新的内存块,我知道我将不得不更改“。”。字符为“ - >”但除此之外,我一直未能制作出我的编译器会接受的东西。我特别不确定声明一个类数组的全局指针。

编辑:对不起我之前应该说过,数组大小将在main()的开头附近计算一次,并且从那时起将保持不变。

5 个答案:

答案 0 :(得分:11)

你可以改变它,这就是它的向量吗?

std::vector<dummie_type> dummie;

int main() {

    //populate();
    //showing alternative loop based approach
    populateWithLoop(calc_size());
    subroutine();
 }

void subroutine()
{
    dummie[3].a = 27; // etc...
    dummie[1].do_stuff();
}

void populate() {

   dummie_type a;
   dummie_type b;
   dummie_type c;

   dummie.push_back(a);
   dummie.push_back(b);
   dummie.push_back(c);

   //will print out 3
   std::cout << dummie.size() << std::endl;

   dummie_type d;
   dummie.push_back(d);

   //will print out 4
   std::cout << dummie.size() << std::endl;


}

populateWithLoop(int n) {

   for(int i=0; i<n; i++) {
       dummie_type temp;
       dummie.push_back(temp);
   }
}

你可以将std :: vector看作一个数组,因此任何现有代码仍然可以继续工作。您可以获得可变长度数组的优点,而无需手动管理内存。

编辑:更新以显示Mick如何填充矢量并获得它的大小。

答案 1 :(得分:5)

  

我知道这将涉及制作一个全局指针,然后将其设置为指向在main中获得malloc或新的内存块,我知道我将不得不更改“。”。字符为“ - &gt;”但除此之外,我一直未能制作出我的编译器会接受的东西。我特别不确定声明一个类数组的全局指针。

这基本上就是它的全部内容。您将dummie声明为dummie_type * dummie;,然后在main中执行dummie = new dummie_type[size];。不,您无需将.更改为->

答案 2 :(得分:1)

将POINTERS数组用于您班级的对象。

使用std::vector,它可能类似于

typedef dummie_type * dummie_ptr;
typedef vector<dummie_ptr> dummie_array;

当然,您必须搜索所有代码,用.替换大量-> s。但是这样,您可以在不调用构造函数和析构函数的情况下调整数组大小。

这是一个例子

int main(int argc, char* argv[])
{
    dummie_array my_array(5); // initial size

    for (int i = 0; i < 5; ++i)
         my_array[i] = new dummie_type(/* constructor parameters */);

    my_array.resize(8);
    for (int i = 5; i < 8; ++i)
         my_array[i] = new dummie_type(/* constructor parameters */);

    for (int i = 0; i < 8; ++i)
         my_array[i]->do_something(/* member function parameters */);

    for (int i = 0; i < 8; ++i)
         delete my_array[i];

    return 0;
}

答案 3 :(得分:1)

如果您要将此作为向量实现,正​​如Glen所建议的那样,当您需要在开头附近进行一次性分配时,您将保留(),例如:

int slots_i_need = 0;
if (/* ... */)
   slots_i_need = 4096;
else
   // ...
// ...
dummie.reserve(slots_i_need);

效率较低的是测试编译器分配的初始容量是否足以满足您的需求。在这种情况下,您不需要重新分配。在第一个push_back期间保留向量的初始容量:

// ...
dummie_type a_dummie = new dummie_type();
dummie.push_back(a_dummie);
if (slots_i_need > dummie.capacity())
   dummie.reserve(slots_i_need);
else
   {} // nothing to do.

答案 4 :(得分:1)

我认为你不需要改变你的访问者。在C ++中,数组与指针几乎没有什么不同。考虑如何将数组传递给函数:


void MyFunc(thing *p)
{
    ...
}

thing aThings[10]; thing *pThings = new thing[10]; MyFunc(aThings); MyFunc(pThings);

然后您应该能够替换


class dummie_type dummie[10];


class dummie_type *dummie;

您将不得不处理“数组”的初始分配。 此表单将允许您保留当前的使用情况。


void subroutine()
{
    dummie[3].a = 27; // etc...
    dummie[5].do_stuff();
}