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

Posted

技术标签:

【中文标题】如何在 C++ 类中初始化可变大小数组?【英文标题】:How do I initialize a variable size array in a C++ class? 【发布时间】:2014-11-29 15:21:13 【问题描述】:

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

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

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

但是,我想这样做:

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

编译器确实不喜欢我的方法,所以我正在寻找另一种处理方式。

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

【问题讨论】:

使用std::vector 一般来说,对于大多数用途,我不是阵列的忠实拥护者。除非您真的需要它们进行一些感知优化,否则std::vector 是您的朋友,并且更有可能随着您的需求变化而变化。但是您可以使用 std::array ... 方便的 C++ 替代 C 数组。 @HostileFork:std::array 不是可变大小。 std::unique_ptr&lt;T[]&gt; 是在构造时设置大小的数组的标准组件。 std::vector&lt;T&gt; 用于在其生命周期内大小可以变化的数组。 更一般地说:您想了解new(啊,当然还有delete)的动态分配。 @BenVoigt 是的,我很清楚。但我最近讨论了这个问题,some people rabidly insist they want an array。去搞清楚。不要向信使开枪。 【参考方案1】:

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

你可以这样做:

#include <memory>
class Classy

    private:
        int arraysize;
        std::unique_ptr<int[]> myarray;

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

Classy::Classy(int parraysize)
    : arraysizeparraysize
    , myarraynew 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;
    

这将允许大小在创建时发生变化,并在之后固定。 std::unique_ptr 会在你的对象死亡时自动销毁数组内容。

【讨论】:

【参考方案2】:

你想用模板来解决这个问题:

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

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

int main()

    Classy<5> hasArrayOfFiveElements;
    return 0;

您可以选择不使用 std::array,而不是使用 c 样式的数组。但是我们正在编写 C++,所以让我们使用我们可用的更好的语言工具:)

【讨论】:

这不会让您按照问题的要求“将大小传递给构造函数”。【参考方案3】:

好吧,我认为在使用经典数组时不使用动态内存分配是无法做到的,但你可以使用 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

【讨论】:

std::vector 需要一个类型 是的,当然,我忘记写了 :D 谢谢,我已经更新了。 为什么用int arraysize;跟踪std::vector的大小?不能只用vector的size()方法吗? 你可以。我试图尽可能少地编辑操作的代码。但最好用 size 方法。【参考方案4】:

您需要使用new[] 动态分配您的数组,然后在您的析构函数中使用delete[]。或者,使用std::vector&lt;int&gt;reserve 传递给构造函数的数量。还有一种方法是使您的类模板化,将size_t 参数用于您希望它拥有的元素数量,但这完全消除了它的动态方面(您还不如使用std::array点。

我知道您希望避免动态分配,但这是做您想做的最有效的方式(因为vector 可能占用比您预期更多的空间)。

【讨论】:

以上是关于如何在 C++ 类中初始化可变大小数组?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Visual C++ 编译器 (Visual Studio 2010) 的可变数组大小出错。如何规避这个问题?

为啥 C++ 可以“填充”初始化一个可变大小的数组?

c ++:使用模板在类中定义可变长度数组

可变数组怎么初始化(可变大小的对象不能被初始化)?

具有可变大小行的 C++ 二维数组

如何在 C++ 中声明后初始化 n 大小的数组