如何在C ++类中初始化可变大小的数组?

时间:2021-01-29 20:26:51

I have a class that needs to store an array with a variable size. Ideally, this size would be defined as a parameter given to the constructor of the class.

我有一个类需要存储一个可变大小的数组。理想情况下,此大小将被定义为给予类的构造函数的参数。

I can define a constant and then work with that, as seen below:

我可以定义一个常量然后使用它,如下所示:

#include <iostream>
#define ARRSIZE 5

class Classy{
    private:
        int myarray[ARRSIZE];

    public:
        Classy();
        void printarray();
};

Classy::Classy(){
    for(int i = 0; i < ARRSIZE; i++){
        myarray[i] = i * i * 2;
    }
}

void Classy::printarray(){
    for(int i = 0; i < ARRSIZE; i++){
        std::cout << myarray[i] << std::endl;
    }
}

However, I'd like to do it like this:

但是,我想这样做:

#include <iostream>
class Classy{
    private:
        int arraysize;
        int myarray[arraysize];

    public:
        Classy(int parraysize);
        void printarray();
};

Classy::Classy(int parraysize){
    arraysize = parraysize;
    for(int i = 0; i < arraysize; i++){
        myarray[i] = i * i * 2;
    }
}

void Classy::printarray(){
    for(int i = 0; i < arraysize; i++){
        std::cout << myarray[i] << std::endl;
    }
}

The compiler really doesn't like my approach though, so I am looking for an alternative way of doing things.

编译器真的不喜欢我的方法,所以我正在寻找另一种做事方式。

I did some googling on the subject, but my searches did not come up fruitful. I found this approach which does it using dynamic memory allocation. This is something I'd like to avoid, so I am looking for a solution that does not rely on that. It might well be (and I'm starting to think) that it is the only elegant solution to my problem (and if this is the case, the question should of course be closed as duplicate).

我做了一些关于这个主题的谷歌搜索,但我的搜索并没有取得丰硕成果。我发现这种方法使用动态内存分配来完成它。这是我想避免的,所以我正在寻找一种不依赖于它的解决方案。它可能(我开始认为)它是我问题的唯一优雅解决方案(如果是这种情况,问题当然应该作为重复关闭)。

4 个解决方案

#1


10  

It is required to use dynamic allocation, because sizeof (Classy) must be a compile-time constant. There's no way for your object's internal size to grow. But dynamic allocation doesn't have to be as complicated as that link suggests.

它需要使用动态分配,因为sizeof(Classy)必须是编译时常量。对象的内部大小无法增长。但动态分配不必像链接所暗示的那样复杂。

You can do it like this:

你可以这样做:

#include <memory>
class Classy
{
    private:
        int arraysize;
        std::unique_ptr<int[]> myarray;

    public:
        Classy(int parraysize);
        void printarray();
};

Classy::Classy(int parraysize)
    : arraysize{parraysize}
    , myarray{new int[arraysize]}
{
    for(int i = 0; i < arraysize; i++){
        myarray[i] = i * i * 2;
    }
}

#include <iostream>
void Classy::printarray()
{
    for(int i = 0; i < arraysize; i++){
        std::cout << myarray[i] << std::endl;
    }
}

This will allow the size to vary at the moment of creation, and be fixed thereafter. std::unique_ptr will take care of automatically destroying the array contents when your object is dying.

这将允许尺寸在创建时改变,并在此后固定。当对象死亡时,std :: unique_ptr将自动销毁阵列内容。

#2


3  

You need to dynamically allocate your array using new[] and then delete[] it in your destructor. Alternatively, use a std::vector<int> and reserve the amount passed to the constructor. Yet one more method is to make your class templated, taking a size_t argument for the amount of elements you want it to have, but that completely removes the dynamic aspect of it (and you might as well be using std::array at that point.

您需要使用new []动态分配数组,然后在析构函数中删除[]。或者,使用std :: vector 并保留传递给构造函数的数量。还有一种方法是让你的类被模板化,为你希望它拥有的元素数量取一个size_t参数,但这完全消除了它的动态方面(你也可能在那时使用std :: array) 。

I know you'd like to avoid dynamic allocation, but it's the most efficient way to do what you want (because vector might take up more space than you expect).

我知道你想避免动态分配,但这是做你想要的最有效的方法(因为矢量可能占用比你期望的更多的空间)。

#3


3  

Well, I think you can't do it without using dynamic memory allocation while using a classic array, but you can use std::vector. You can do it like this:

好吧,我认为你不能在使用经典数组时不使用动态内存分配,但你可以使用std :: vector。你可以这样做:

#include <iostream>
class Classy{
    private:
        int arraysize;
        std::vector<int> myArrayOfInts;

    public:
        Classy(int parraysize);
        void printarray();
};

Classy::Classy(int parraysize){
    arraysize = parraysize;
    for(int i = 0; i < arraysize; i++){
        myArrayOfInts.push_back(i * i * 2);
    }
}

void Classy::printarray(){
    for(int i = 0; i < myArrayOfInts.size(); i++){ //you could also use arraysize, but then you
        std::cout << myArrayOfInts[i] << std::endl;//must update it when you add or remove any
    }                                              // element from vector
}

#4


1  

You want to use templates to solve this problem:

您想使用模板来解决此问题:

#include <array>

template<std::size_t ArraySize>
class Classy final
{
public:
    static const std::size_t size = ArraySize;

    /* The rest of your public interface here */
private:
    std::array<int, ArraySize> m_array;
};

Then you can use your class like this:

然后你可以像这样使用你的类:

int main()
{
    Classy<5> hasArrayOfFiveElements;
    return 0;
}

You could very well opt to not use std::array, in preference for a c-style array. But we're writing C++, so let's use the better language facilities we have available to us :)

你可以选择不使用std :: array,而不是使用c风格的数组。但我们正在编写C ++,所以让我们使用我们可用的更好的语言设施:)

#1


10  

It is required to use dynamic allocation, because sizeof (Classy) must be a compile-time constant. There's no way for your object's internal size to grow. But dynamic allocation doesn't have to be as complicated as that link suggests.

它需要使用动态分配,因为sizeof(Classy)必须是编译时常量。对象的内部大小无法增长。但动态分配不必像链接所暗示的那样复杂。

You can do it like this:

你可以这样做:

#include <memory>
class Classy
{
    private:
        int arraysize;
        std::unique_ptr<int[]> myarray;

    public:
        Classy(int parraysize);
        void printarray();
};

Classy::Classy(int parraysize)
    : arraysize{parraysize}
    , myarray{new int[arraysize]}
{
    for(int i = 0; i < arraysize; i++){
        myarray[i] = i * i * 2;
    }
}

#include <iostream>
void Classy::printarray()
{
    for(int i = 0; i < arraysize; i++){
        std::cout << myarray[i] << std::endl;
    }
}

This will allow the size to vary at the moment of creation, and be fixed thereafter. std::unique_ptr will take care of automatically destroying the array contents when your object is dying.

这将允许尺寸在创建时改变,并在此后固定。当对象死亡时,std :: unique_ptr将自动销毁阵列内容。

#2


3  

You need to dynamically allocate your array using new[] and then delete[] it in your destructor. Alternatively, use a std::vector<int> and reserve the amount passed to the constructor. Yet one more method is to make your class templated, taking a size_t argument for the amount of elements you want it to have, but that completely removes the dynamic aspect of it (and you might as well be using std::array at that point.

您需要使用new []动态分配数组,然后在析构函数中删除[]。或者,使用std :: vector 并保留传递给构造函数的数量。还有一种方法是让你的类被模板化,为你希望它拥有的元素数量取一个size_t参数,但这完全消除了它的动态方面(你也可能在那时使用std :: array) 。

I know you'd like to avoid dynamic allocation, but it's the most efficient way to do what you want (because vector might take up more space than you expect).

我知道你想避免动态分配,但这是做你想要的最有效的方法(因为矢量可能占用比你期望的更多的空间)。

#3


3  

Well, I think you can't do it without using dynamic memory allocation while using a classic array, but you can use std::vector. You can do it like this:

好吧,我认为你不能在使用经典数组时不使用动态内存分配,但你可以使用std :: vector。你可以这样做:

#include <iostream>
class Classy{
    private:
        int arraysize;
        std::vector<int> myArrayOfInts;

    public:
        Classy(int parraysize);
        void printarray();
};

Classy::Classy(int parraysize){
    arraysize = parraysize;
    for(int i = 0; i < arraysize; i++){
        myArrayOfInts.push_back(i * i * 2);
    }
}

void Classy::printarray(){
    for(int i = 0; i < myArrayOfInts.size(); i++){ //you could also use arraysize, but then you
        std::cout << myArrayOfInts[i] << std::endl;//must update it when you add or remove any
    }                                              // element from vector
}

#4


1  

You want to use templates to solve this problem:

您想使用模板来解决此问题:

#include <array>

template<std::size_t ArraySize>
class Classy final
{
public:
    static const std::size_t size = ArraySize;

    /* The rest of your public interface here */
private:
    std::array<int, ArraySize> m_array;
};

Then you can use your class like this:

然后你可以像这样使用你的类:

int main()
{
    Classy<5> hasArrayOfFiveElements;
    return 0;
}

You could very well opt to not use std::array, in preference for a c-style array. But we're writing C++, so let's use the better language facilities we have available to us :)

你可以选择不使用std :: array,而不是使用c风格的数组。但我们正在编写C ++,所以让我们使用我们可用的更好的语言设施:)