Pages: [1]   Go Down
Author Topic: initialize a vector in a constructor  (Read 1563 times)
0 Members and 1 Guest are viewing this topic.
italy
Offline Offline
Full Member
***
Karma: 3
Posts: 223
Muuuuu
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
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"
Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 65
Posts: 2111
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
template< const int i_Elements > class myClass{

  private:

    unsigned long myVector[ i_Elements ];
};

Instantiate an object like
Code:
myClass< 4 > m_Class1;

//rather than
myClass m_Class1( 4 );

Logged


Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

or use dynamic memory ... malloc() ?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

italy
Offline Offline
Full Member
***
Karma: 3
Posts: 223
Muuuuu
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

italy
Offline Offline
Full Member
***
Karma: 3
Posts: 223
Muuuuu
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This compiles:

Code:
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:

Code:
18
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

Quote
(I guess that's technically optional on a uC)
Uh, no, freeing memory is not optional on a uC.

Quote
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?

Logged

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

Quote
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.

Quote
Quote
(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.
Logged

Seattle, WA
Offline Offline
God Member
*****
Karma: 11
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley )

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.

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


North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 65
Posts: 2111
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Dynamic memory doesn't win in this situation.

Code:
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.
Logged


italy
Offline Offline
Full Member
***
Karma: 3
Posts: 223
Muuuuu
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks
Logged

Pages: [1]   Go Up
Jump to: