Object as an objects property.

Hello.

I am trying to write object oriented code for Arduino.
Being more used to higher level languages, I cant find the correct syntax to do what I want.
Here is how I would instinctly write it :

Class Instrument {
    public:
        Instrument(){
            this->_piano_key = new Debounce( 10,10 );
        }
        boolean read(){
            return this->_piano_key->read();
        }
    private:
        Debounce _piano_key;
}

Of course this doesn't work ...
Can somebody help me find the right syntax for this ?

Thanks a lot !

Something in the likes of:

Instrument.h

#ifndef INSTRUMENT_H
#define INSTRUMENT_H

#include <WProgram.h>
#include "Debounce.h"

class Instrument {
    public:
        Instrument();
        bool read();
    private:
        Debounce _piano_key;
};//<-- remember this ;
#endif

Instrument.cpp

#include "Instrument.h"

Instrument::Instrument() : _piano_key( 10,10 ){
  //
}

bool Instrument::read(){
  return _piano_key.read();
}

:slight_smile:

This works, thanks a lot !

Just out of curiosity, is there a way to do this in the code block of the constructor ?
Like if I want to do something like this :

Instrument::Instrument( boolean stuff ){
    if( stuff ){
        this->_piano_key = new Debounce( 20,20 );
    }else{
        this->_piano_key = new Debounce( 40,21 );
    }
}

This could easily lead to some daunting debugging but:

Instrument::Instrument( boolean stuff ) : _piano_key( stuff?20:40 , stuff?20:21 ){
    //
}

You would probably be better off by passing a Debounce object as a parameter to the constructor.
But, it would ofcource depend on the task at hand.

[edit]

You would probably be better off by passing a Debounce object as a parameter to the constructor.

Such as:

Instrument.h

#ifndef INSTRUMENT_H
#define INSTRUMENT_H

#include <WProgram.h>
#include "Debounce.h"

class Instrument {
    public:
        Instrument(Debounce& piano_key);
        bool read();
    private:
        Debounce* _piano_key;
};//<-- remember this ;
#endif

Instrument.cpp

#include "Instrument.h"

Instrument::Instrument(Debounce& piano_key){
  _piano_key = &piano_key;//assign the adress of piano_key to the value of _piano_key
}

bool Instrument::read(){
  return _piano_key->read();
}

Sketch.pde

#include <Instrument.h>

Debounce myPianoKeyDebounce = Debounce(20,20);
Instrument myInstrument = Instrument( myPianoKeyDebounce );

void setup(){
  Serial.begin(9600);
  Serial.println( (byte)myInstrument.read() , DEC );
}

void loop(){/*nothing to loop*/}

[/edit]

By default, you cannot use C++'s operator new to create instances at runtime. (You only have 1KB or 2KB of RAM, so that's probably a good thing.) However, since the libraries do support C's malloc(), you can enable operator new yourself.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230935955/3#3

Enabling new/delete (on a platform that does not support them) can lead to some very nasty bugs.

If one pass something to free() that has not previously been allocated with malloc / realloc one would be surprised of the results.

I think it would need to be properly documented that one can not free something that has not been created using operator new.

[correct me if I am wrong :)]

If you use operator new, you must use operator delete, but not for the worry that you state, exactly.

Yes, as you say, you should always match the same heap manager routines, choosing compatible allocation and deallocation together. The malloc()/realloc() go with free(), for example.

Also, new goes with delete, but these aren't functions, they're operators. In C++, you need to use the official operator new and operator delete so that constructors and destructors get called appropriately. It's okay to define the operators to use the malloc/free scheme as I show above, and in fact, that's what 99% of C++ compilers would do, until they want to do fancy things to integrate with leak detectors or other debugging tools.

For a beginner that is overeager with resource efficiency could be tempted to do this:

      int arr[10] = { 1,2,3,4,5,6,7,8,9,10};
      int* arra = arr;
      Serial.println(arra[1]);
      delete arra;

This would give a runtime error on a compiler that supports new/delete by default. But not on the Arduino.

I simply think of it as 'bad practice' to use new/delete on a platform that a) does not support it natively and b) have a limited amount of SRAM.

[ It sure is useful for us programmers that would've used malloc/free anyways. Makes for a cleaner code. ]

That is just one of many issues with heaps. Combining heaps with microcontrollers is very rarely worth the considerable additional risk.

You would probably be better off by passing a Debounce object as a parameter to the constructor.

Remove the word "probably" and I agree!

  • Brian