【问题标题】:How do I initialize a variable size array in a C++ class?如何在 C++ 类中初始化可变大小数组?
【发布时间】: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。去搞清楚。不要向信使开枪。

标签: c++ arrays oop


【解决方案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)
    : 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;
    }
}

这将允许大小在创建时发生变化,并在之后固定。 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 可能占用比您预期更多的空间)。

    【讨论】:

      猜你喜欢
      • 2023-02-23
      • 1970-01-01
      • 2014-09-28
      • 2021-06-08
      • 2021-07-19
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多