float array[]
either is an extension or just doesn't compile. For a C-style static array, Type name[constexpr_size]
is used. For a dynamic array, Type* name
is stored as a pointer to the beginning of the storage allocated.
Dynamic Array
OK, we need the second option. Then, we start with your snippet
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
};
(see member initializer as an explanation to those {}
initializers in float* array{}
and int size{}
).
What about
Arrayclass(int arraySize) { float * array = new float[arraySize](); }
, you create a local float*
which dies at the end of scope (=the constructor). You probably meant to store that new
ly allocated array in (this->
)array
:
Array(int newSize) { // BAD CODE, see below
array = new float[newSize]{};
size = newSize;
}
but the code above is like writing float* p; p = something
(create default, than initialize it) instead of float* p{something}
(initialize on creation), let's improve it by using member initializer list:
Array(int newSize): array{new float[newSize]{}}, size{newSize} {}
Now, your array (almost) can construct and destruct properly.
==========
However, there's still an issue left: code such as
{
Array a1{42};
Array a2{a1}; // copy construction
}
has undefined behavior and in practice (in this case) should/might crash your application. Why? Because it works as something like (size
s omitted):
{
float* array1{new float[42]{}};
float* array2{array1};
delete[] array1;
delete[] array2; // that UB (double free); the same dynamic array is deleted twice
}
Well, it is a topic for another "lesson". See the rule of three (five) (zero). In general, see RAII and copy/move-semantics.