AndrewLee
AndrewLee

Reputation:

c++ array declaration in a header

I was wondering if it is possible to declare an array (size not known at this time), as a private member of a class and later set the size in the constructor of the class. For example:

class Test {
int a[];
public:
Test(int size);
};

Test::Test(int size) {
a[size];   // this is wrong, but what can i do here?
}

Is this possible or should I use dynamic arrays? Thanks!

Upvotes: 12

Views: 42294

Answers (7)

JaredPar
JaredPar

Reputation: 754565

No this is not possible. Array declarations in headers must have constant sized value. Otherwise it's impossible for constructs like "sizeof" to function properly. You'll need to declare the array as a pointer type and use new[] in the constructor. Example.

class Test { 
    int *a;
public:
    Test(int size) {
       a = new int[size];
    }
    ~Test() { delete [] a; }
private:
    Test(const Test& other);
    Test& operator=(const Test& other);
};

Upvotes: 16

Loki Astari
Loki Astari

Reputation: 264361

Short Answer: No (The size of an array is defined at compile time only)
Long Answer:

You can use a vector to achieve the same result:

class Test
{
    std::vector<int> a;
    public:
        Test(std::size_t size):
            a(size)
        {}
};

Upvotes: 17

Greg Hewgill
Greg Hewgill

Reputation: 992827

As other answers have pointed out, the size of an array is fixed at compile time. However, by using templates you can parameterise the size at compile time:

template <int N> class Test {
    int a[N];
public:
    Test() { }
};

Test<5> test;
Test<40> biggertest;

This technique does not let you compute the size at run time (as the dynamic std::vector solution does), but depending on your needs this may be sufficient.

Upvotes: 5

orip
orip

Reputation: 75427

See Martin's solution (use std::vector), and remember that even if you need to pass a buffer to a C API std::vector lets you do it by passing &vec[0] :

std::vector<char> vec(10);
memset(&vec[0], 0, vec.size());

It's guaranteed to work, but only if the vector isn't empty (C++ quirks, <sigh>).

Upvotes: 2

Dave
Dave

Reputation: 895

What you're talking about is not possible. Classes always have a constant size. You could have your class use a pointer to a dynamically allocated array or you could use a std::vector.

Upvotes: 0

Adam Rosenfield
Adam Rosenfield

Reputation: 400174

No, this is not possible. You should use a dynamic array such as an std::vector. C99 allows a struct to have an unsized array as the last member only, but even when you do this you still have to manually allocate the memory yourself, e.g. with malloc().

Upvotes: 0

Uri
Uri

Reputation: 89729

First of all, it is generally better to initialize things in the initialization list of the constructor, not in the body of the constructor.

You can only initialize an array with a predefined bound if you know that bound at compile time. In this situation, you will need to dynamically allocate the space.

You must remember then to have a destructor that would delete the array when the object is destroyed or you would get a memory leak.

Upvotes: 3

Related Questions