Polymorphism Trouble

I have two different LED displays, that I’d like to share an interface between. One is the HT1632 driver board from Sure Electronics, and one is a home brew RGB array.

I’d like the (abstract) base class Display to contain all the arithmetic for drawing lines and ellipses and the two concrete derived classes to contain just a single method:

setPixel(x, y, color).

I have code that compiles, but does not execute.

Simple line test. In Test01_Ojbect.pde, I execute ht1632.line(0, 7, 31, 7, RED). I expect this to actually run Display::line(), but it does not. When I copy the code into HT1632.cpp, it works.

Suggestions and comments welcome.

Test01_Object.pde

#include "HT1632.h"
#include "Wire.h"
#include "Display.h"

HT1632 ht1632;

void setup(){
  Serial.begin(9600);
  ht1632_setup();
}

void loop(){
  ht1632.line(0, 7, 31, 7, RED);
  delay(1000);
}

HT1632.h (3.74 KB)

HT1632.cpp (16.3 KB)

Display.h (1.91 KB)

Display.cpp (1.12 KB)

I expect this to actually run Display::line(), but it does not.

What does it do instead?

Why have you provided an implementation of HT1632::line if you expect Display::line() to be called? Or, if you provide an implementation of HT1632::line, why do you expect the base class' method to be called instead?

I think your expectation is unreasonable.

From what I remember from my golden age, for polymorphism to take place, functions in the base class need to be declared virtual.

On the other hand, the arduino compiler does not handle operator "new" as a normal (e.g. Visual C++) compiler would. I don't remember seeing arduino code using new operator. Most of the code I've seen (e.g. Wire library, DS1307 etc) uses global instances of a class.

More research and testing is required :)

@PaulS, Thank you for looking through the code.

@FlorinC, I will try playing with the function declarations. Thanks for having a look.

I'll post back here any solutions.

:)

I didn't think that would compile, and it doesn't:

HT1632.cpp:510: error: no 'void HT1632::line(double, double, double, double, uint8_t)' member function declared in class 'HT1632'

There is no "line" function declaration in HT1632 class, and thus you can't implement the function.

I have code that compiles, but does not execute.

How does it compile?

I juggled the code around a bit to get it to compile (eg. deleting the font stuff which I didn't have) and after deleting the HT1632::line function altogether, found that the Display::line function did indeed get called.

It's a member function provided only in the base class, you expect it to be called.

I expect this to actually run Display::line(), but it does not.

And it did, once I made those changes.

@nick, thanks for looking at this. Sorry for the mix up. I have been trying different things to see if I could get it to work. You nailed it by commenting out that function. I’m glad you got it to work. I’ll have to take another look.

Justin

@FlorinC, you are a friggin' Genius! It must have been running the base class version of setPixel(). Declaring it virtual in the base class did the trick!

Thanks for taking a look.

Justin

Base.h

class Base{
  virtual void do_something();
  void base_gets_called();
};

Derived.h

class Derived{
  void do_something();
  void base_gets_called();
}

Test.pde

Derived d;
...
  d.do_something() // executed method in Derived
  d.base_gets_called(); // Base method called (Derived method hidden)
...

By the way, the derived class can call the base class. eg.

void Derived::do_something ()
{
Base::do_something ();  // do common processing first

// extra stuff here for derived class

}

(Or the order can be the other way around).