【问题标题】:C++ Dynamic Array allocation in Classes类中的 C++ 动态数组分配
【发布时间】:2021-11-24 13:12:55
【问题描述】:

我目前正在学习 C++ 的基础知识,并且遇到了以下类数组的问题。

class Arrayclass {
private:
    int arraySize;
    float array[];

public:
    Arrayclass(int arraySize) {
        float * array = new float[arraySize]();
}

~Arrayclass() {
   delete[] array;
}
}

据我所知,在构造函数中初始化的数组实际上并不对应于新类中的存储数组,因此当我在我的主类中初始化一个新类时,创建的数组持有0 值。我很抱歉我的解释不清楚,只是想了解构造函数中初始化的数组与我私有的数组之间的关系。

【问题讨论】:

  • 你在构造函数中声明了一个局部变量array,它与数据成员array无关。只需将array = new float[arraySize](); 放入构造函数中即可。
  • 构造函数定义了一个名为array 的新变量,它与名为array 的类成员没有任何关系,并且在构造函数返回时不再存在,这无济于事。相反,在构造函数初始化列表(不在构造函数主体中)中初始化 array 成员,即 ArrayClass(int arraySize) : array(new float[arraySize] {};。此外,管理资源的类(如动态分配的数组,在您的情况下)通常需要手动实现复制构造函数、复制赋值和析构函数。查找“三规则”以获取相关信息。
  • float array[]; 在标准 C++ 中是不允许的。也许你的意思是float * array;,但你应该使用std::vector<float> array;

标签: c++ arrays class


【解决方案1】:

float array[]

要么是扩展,要么就是无法编译。对于 C 样式的静态数组,使用 Type name[constexpr_size]。对于动态数组,Type* name 存储为指向已分配存储空间开头的指针。

动态数组

好的,我们需要第二个选项。然后,我们从你的 sn-p 开始

class Array { // "class Arrayclass" -> "class Array", no need to repeat ourselves
private:
    float* array{};
    int size{}; // "Array::arraySize" -> "Array::size", again
public:
    ~Array() { delete[] array; } // your destructor is fine
};

(请参阅 member initializer 作为对 float* array{}int size{} 中的 {} 初始化器的解释)。

怎么样

Arrayclass(int arraySize) { float * array = new float[arraySize](); }

,你创建了一个本地的float*,它在作用域结束时死掉(=构造函数)。您可能打算将 newly 分配的数组存储在 (this->)array:

Array(int newSize) { // BAD CODE, see below
    array = new float[newSize]{};
    size = newSize;
}

但上面的代码就像写float* p; p = something(创建默认值,而不是初始化它)而不是float* p{something}(创建时初始化),让我们使用member initializer list改进它:

Array(int newSize): array{new float[newSize]{}}, size{newSize} {}

现在,您的数组(几乎)可以正确构造和销毁了。

===========

但是,还有一个问题:代码如

{
    Array a1{42};
    Array a2{a1}; // copy construction
}

undefined behavior 并且在实践中(在这种情况下)应该/可能会使您的应用程序崩溃。为什么?因为它的工作方式类似于(sizes 省略):

{
    float* array1{new float[42]{}};
    float* array2{array1};
    delete[] array1;
    delete[] array2; // that UB (double free); the same dynamic array is deleted twice
}

嗯,这是另一个“课程”的主题。见the rule of three (five) (zero)。一般来说,请参阅 RAII 和复制/移动语义。

【讨论】:

  • “应该让你的应用程序崩溃”->“有未定义的行为”。当这表现为“你的应用程序崩溃”时,你是幸运
  • @Caleth 添加了这个。
猜你喜欢
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 2014-08-19
  • 2022-11-25
  • 2023-03-17
  • 1970-01-01
  • 2012-11-23
相关资源
最近更新 更多