I'm writing some Arduino code and attempting to use inheritance in some classes. I have a class "Actor" (my base class) and a class "Marble" (which inherits from Actor). Here are the header files:
Actor.h:
#ifndef Actor_h
#define Actor_h
#include "Arduino.h"
class Actor
{
public:
Actor();
void speak();
private:
};
#endif
Marble.h:
#ifndef Marble_h
#define Marble_h
#include "Arduino.h"
#include "Actor.h"
class Marble : public Actor {
public:
Marble();
virtual void speak();
private:
};
#endif
Actor.cpp:
#include "Arduino.h"
#include "Actor.h"
Actor::Actor()
{
}
void Actor::speak() {
Serial.println("Actor");
}
Marble.cpp:
#include "Arduino.h"
#include "Marble.h"
void Marble::speak() {
Serial.println("Marble");
}
And finally, in the loop function I do:
void loop() {
Marble marble;
Actor children[2];
children[0] = marble;
children[0].speak();
Which results in "Actor" being printed.
I discovered this nice link which seems similar to my issue, but the resolution does not seem to work for me: http://arduino.cc/forum/index.php?topic=41884.0
So. It seems like when I create my array of "Actors" and try and stick Marble in there it gets cast to an Actor, or something like that. Problem is, I'll have a few different characters that will all inherit from "Actor" and I'd like an array of them to iterate over and call overridden methods on them.
So, perhaps the problem is how I'm approaching this problem, or maybe there's some syntax errors? I don't know!
Thanks for your help, Kevin
You need to declare
speak
asvirtual
in theActor
class, not just in theMarble
class; without that,Actor::speak
is a non-virtual function, so you will always be called in preference to the virtualMarble::speak
.For what it's worth, this has nothing to do with the Arduino: it's just a straight C++ issue.
Your problem is that
children
is an array of typeActor
. The linechildren[0] = marble
is taking aMarble
object, converting it to anActor
object and copying the results tochildren[0]
. Since the call tochildren[0].speak()
is on anActor
, you get theActor
version.In order for this to work the way you want, you need to copy a pointer or reference to the object rather than the object itself. That is, you want something like `Actor* children[2]':
Of course if
children
has scope outside ofloop
, this will fail utterly and you'll need to usenew
to create your marbles.Better yet, assuming Arduino has the STL, you should use
vector
andshared_ptr
or something similar.[Update] As Philip notes, this will also require that the
speak
method inActor
be declared virtual.