initialize a vector in a constructor

Hello, I want to initialize a long vector of a constant N_ELEMENTS elements in a constructor. I know the size of the vector only when initializing the object of that class. Do you know how can I declare it? I have tried in this way:

private:
    const int N_ELEMENTS;
    unsigned long myVector[N_ELEMENTS]
public:
myClass(int N_ELEMENTS=20):myVector[N_ELEMENTS]; //the constructor

but the complier say "invalid use of non-static data member"

The error is for the line

unsigned long myVector[N_ELEMENTS]

as N_ELEMENTS must be initialised during the constructor, the size cannot be known at compile time, late binding impedes this approach.

What you need is early binding.

template< const int i_Elements > class myClass{

  private:

    unsigned long myVector[ i_Elements ];
};

Instantiate an object like

myClass< 4 > m_Class1;

//rather than
myClass m_Class1( 4 );

or use dynamic memory ... malloc() ?

thanks pYro_65! do you also hknow how to declare the template in constructor in the cpp file? I have declared the class in this way “template< const int i_Elements > class myClass” in the header.
In the cpp declarations like this one:
“template< const int i_Elements> myClass::myClass()” seems not to be accepted.

@robtillaart Yes malloc is a solution but I prefer to avoid pointers in C++ because they increase the probability of errors. I prefer to work more with class and object. Anyway you're right

This compiles:

template< const int i_Elements > class myClass
  {
  private:
  const int n_Elements;
  unsigned long myVector [i_Elements];
  public:
   myClass () : n_Elements (i_Elements) {};
  };

void setup ()
{
 myClass<4> foo;
 Serial.begin (115200);
 Serial.println (sizeof foo, DEC);
}

void loop () {}

Output:

18

However you can't replace the 4 by a variable, as the template doesn't know what code to generate. Then you need dynamic memory allocation, or use the STL.

Yes malloc is a solution but I prefer to avoid pointers in C++ because they increase the probability of errors.

No. The use of pointers does not increase the probability of errors. The misuse of pointers, on the other hand, does. Learning to properly use pointers is not a waste of time and effort.

PaulS:

Yes malloc is a solution but I prefer to avoid pointers in C++ because they increase the probability of errors.

No. The use of pointers does not increase the probability of errors. The misuse of pointers, on the other hand, does. Learning to properly use pointers is not a waste of time and effort.

For every line you must type, there is a change you will mistype it or forget to do it. Thus, since you must declare the pointer, allocate memory from it, and free the memory (I guess that's technically optional on a uC) as opposed to just defining the object, you have the opportunity to make more errors with pointers.

I also consider it better design to use templates rather than malloc when possible.

For every line you must type, there is a change you will mistype it or forget to do it. Thus, since you must declare the pointer, allocate memory from it, and free the memory

Oh, I know. I just hate when I have to think and code at the same time.

(I guess that's technically optional on a uC)

Uh, no, freeing memory is not optional on a uC.

as opposed to just defining the object, you have the opportunity to make more errors with pointers.

Better to let someone else do the thinking, eh?

PaulS:

For every line you must type, there is a change you will mistype it or forget to do it. Thus, since you must declare the pointer, allocate memory from it, and free the memory

Oh, I know. I just hate when I have to think and code at the same time.

as opposed to just defining the object, you have the opportunity to make more errors with pointers.

Better to let someone else do the thinking, eh?

I'm not saying it's hard, just it increases the probability of errors. People seem to have figured this out, since they invented smartptr and similar constructs so one doesn't need to worry about it.

(I guess that's technically optional on a uC)

Uh, no, freeing memory is not optional on a uC.

For a global object, you want it to last until the memory is forcefully cleared by a reset. This thread is about allocating and forgetting about it. Obviously you need to free memory if you're going to be repeatedly allocating it.

I will definitely vote for dynamic allocation. Seems a lot cleaner than templates for ints. (Although I will apologize in advance if this needs tweaks to compile on the stock Arduino avr-gcc... I should keep a copy of old compilers just to make sure my forum posts still compile :) )

After the constructor is finished, you never have to think about myVector as a pointer. Just treat it like an array, except don't use sizeof() on it.

class myClass
{
private:
  int N_ELEMENTS;
  unsigned long *myVector;
public:
  myClass(int N_ELEMENTS=20)
  {
    myVector = new unsigned long[N_ELEMENTS];
  }
  ~myClass()
  {
    delete[] myVector;
  }
};

Dynamic memory doesn’t win in this situation.

template< const int i_Elements > class myClass
  {
  private:
  unsigned long myVector [ i_Elements ];
  public:
   myClass(){};
  };

To start off with,
No SRAM is used storing the count of elements as the object is explicitly bound to i_Elements value.
No new and delete operators are required.
No destructor is required due to automatic variable destruction.

Almost exactly the same, just doing it in 0 lines of code.

thanks