0

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,

Cactus Golov
  • 3,474
  • 1
  • 21
  • 41
Demod
  • 53
  • 1
  • 1
  • 8
  • If you need array of varying size then I would look into vector/map instead – Tymoteusz Paul Jan 05 '14 at 09:38
  • I don't need an array whose size vary. The size if fixed for each array, it's juste that it's not the same for every instance. For exemple for object1 it's 5 and for object2 it's 10. – Demod Jan 05 '14 at 09:41
  • I perfectly understand that, and yet you could just define a vector and then allocate it with different sizes for each child. That will save you the need of using template. – Tymoteusz Paul Jan 05 '14 at 09:42
  • Okay, truth is I'm currently learning and I haven't reach the part about STL and classic containers. – Demod Jan 05 '14 at 09:46
  • Nitpick: your class does not have an array attribute. It has a pointer. You can make it point to a dynamically allocated array, but it is still a pointer. It is important to distinguish pointers from arrays. – juanchopanza Jan 05 '14 at 09:48
  • not a problem, we are here to help! And for future if you are replying to someone - tag them with @name so they will get a notification (unless they own question/answer, then they will get it anyway). – Tymoteusz Paul Jan 05 '14 at 09:51
  • It's worth mentioning that while `std::vector` is probably most appropriate at the moment, despite the fact it can change size, there is a proposal in progress for a `std::dynarray` which is fixed-size. It should be usable within the next year or so (but not part of the standard until C++17). – Joseph Mansfield Jan 05 '14 at 10:54

2 Answers2

4

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.

Community
  • 1
  • 1
Cactus Golov
  • 3,474
  • 1
  • 21
  • 41
  • @ Anton Golov & Jarod42 : Thanks for the answers. Do you have any recommandations concerning learning books ? – Demod Jan 05 '14 at 10:07
  • @Demod: [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Blastfurnace Jan 05 '14 at 10:10
  • @Jarod42: Yeah, if I'm suggesting unique_ptr might as well, thanks. – Cactus Golov Jan 05 '14 at 10:30
  • @Demod: If you're a beginner programmer, try [C++ Primer](http://www.amazon.com/dp/0321714113). (Though I'm not sure I'd recommend C++ then...) – Cactus Golov Jan 05 '14 at 10:30
  • @AntonGolov I already programmed in Java, C and Matlab. But I'm not a computer science student, I'm more into applied mathematics, and I use programming to do calculations and implementations. Currently I want to learn C++ as I need a specific data structure that has been implemented in C++. Sadly, I dont really have the time to go into a 1K-pages book right now. – Demod Jan 05 '14 at 10:45
  • @Demod: Well, if you need something quick, get [Accelerated C++](http://www.amazon.com/dp/020170353X/). It's significantly shorter, and the fact that it's somewhat old probably won't matter for you anyway. – Cactus Golov Jan 05 '14 at 11:42
  • @AntonGolov Thank you, I'll start reading it. I'll go later into a more detailed book (like Primer) if I feel the need (and hopefully if I have the time ^^' ) – Demod Jan 05 '14 at 11:58
0

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.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380