Вопрос

I would like to know, if I have a class with an array attribute whose size is not the same for all instances :

class myObject{

private:
    int size;
    int* array;

// other methods/attributes

};

Is it obligatory allocated using new ?

explicit myObject(int size = 0):size(size){
    array = new int[size];
}

Even if in the main(), I always use constant parameters to create the instances of the class ? (Meaning I know every array size at compile time).

int main{
    myObject object (5);
    return 0;
}

Apparently something like :

private:
    int size;
    int array[size];

wont work, no ?

That means that array attribute whose size are not constant of the class are obligatory on the heap ?

Thank you for your answers,

Это было полезно?

Решение

That class contains no array. What you called array is a pointer; you cannot store any ints in it. If you really do just store a pointer, you'll have to allocate the memory yourself somehow; it can't magically appear. You'll also have to deallocate it yourself, and make sure that copying and assigning myObject objects doesn't cause any issues.

However, it's unlikely that a pointer is really the best way to do things. The standard library provides the std::vector class template which lets you use almost exactly the syntax you want:

class myObject {
    std::vector<int> vector;

public:
    myObject() {};
    explicit myObject(std::size_t n) : vector(n) {}
};

With this in place you can create myObjects and they'll have the right amount of storage ready for them. It'll likely be dynamically allocated using operator new[], just like if you'd do it manually, but you don't have to worry about copying or deleting it.

int main() {
    myObject a; // default-constructed, vector is empty.
    myObject b(10); // std::size_t constructor, vector has 10 elements.
} // scope exit, b and a destroyed.

You can use the vector member much like if it was an array; the only thing it does not support is implicit decay to pointer, but the data member function makes up for even that.

As an alternative, if you always know the size at compile-time you can change the class into a class template and make the size a template parameter:

template<std::size_t N>
class myObject{
    std::array<int, N> array;

    // other methods/attributes
};

However, note that you now cannot use myObject<10> to a function expecting myObject<20>.

It is unlikely that you want more control than the above possibilities provide -- std::vector can be given an allocator, so it can do almost all work for you -- you could use std::unique_ptr<int[]> and make_unique together to make things work for you. However, if you need this kind of power, you probably know it yourself.

As a closing note, if you're just learning C++ and your book doesn't cover std::vectors somewhere early on, perhaps it's best to get a different book; they're one of the most commonly-useful data structures in the standard library and definitely not something to be left in an appendix.

Другие советы

If you need a variable sized array as a member of a class, don't use built-in arrays directly. Instead, use std::vector<T>, e.g.:

class myObject {
    std::vector<int> array;
public:
    explicit myObject(int size = 0): array(size){}
};

You can get the std:vector<int>'s size using array.size(), i.e., there is no need to store the size separately. Also, the content is automatically default initialized.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top