This is my first foray into C++ in a long time, so please go easy on me.
I'm trying to create several abstract base classes, which I will then extend and implement in several different ways. Most of the time only one of these implementations will be used -- I'm mostly writing wrappers for other libraries, and the libraries are direct replacements for each other. So I might have an XML reader abstract class, for example, and two implementations of this class, for libexpat and libmxml; but, of course, only one class needs to be compiled with the program.
So, my problem. I want other parts of the program to be able to declare instances of the abstract class. Of course this can't be done, but . . . well . . . here's what I mean.
Base class:
Code:
class graphics {
protected:
bool quit_requested;
int framerate;
public:
static const int DEFAULT_FRAMERATE;
public:
graphics();
virtual ~graphics() {}
virtual void init() = 0;
virtual void get_events() = 0;
virtual void repaint() = 0;
virtual void update(bool all = 0) = 0;
virtual void clear_screen() = 0;
virtual void delay() = 0;
virtual void set_framerate(int rate = DEFAULT_FRAMERATE)
{ framerate = rate; }
virtual int get_framerate() const { return framerate; }
virtual void set_quit_requested(bool quit = false)
{ quit_requested = quit; }
virtual bool get_quit_requested() const { return quit_requested; }
};
Implementation class for the SDL (yes, I went overboard with namespaces):
Code:
class sdl : public mundus::graphics::graphics {
private:
SDL_Surface *screen;
FPSmanager fpsm;
public:
sdl();
virtual ~sdl();
virtual void init();
virtual void get_events();
virtual void repaint();
virtual void update(bool all = 0);
virtual void clear_screen();
virtual void delay();
virtual void set_framerate(int rate = DEFAULT_FRAMERATE);
static SDL_Rect build_sdl_rect(rect &rect);
private:
void handle_event(SDL_Event &event);
};
Code that uses a graphics class:
Code:
class mundus {
protected:
graphics::sdl::sdl graphics;
object objects;
public:
void run();
object &get_objects() { return objects; }
};
// ...
void mundus::run() {
graphics.init();
for(;;) {
graphics.get_events();
if(graphics.get_quit_requested()) break;
graphics.clear_screen();
objects.repaint();
graphics.repaint();
graphics.delay();
}
}
The trouble, of course, is that I don't want to declare an instance of sdl in the mundus class like this:
Code:
graphics::sdl::sdl graphics;
Or even like this:
Code:
graphics::graphics *graphics = new graphics::sdl::sdl();
I want to declare an instance of the graphics class, using whatever implementation is available. Of course, another implementation would likely have a different name, and so the declaration I'm using at the moment would be invalid.
Any thoughts on how to do this?
My thoughts have ranged from creating a base "creation" class that would know how to construct every class type (difficult and error-prone), to using macros (ugh), to implementing the base class directly instead of extending it (what if I want to add other members to the class?), to not bothering with a base class at all, but just having different implementations compatible (too ad-hoc). I guess overloading the new operator might work too -- but I think I'm looking for overly complicated solutions here.
Any thoughts on my design? Inheritance might not be the best way to go, it's just what first came to mind. It makes sense, but it's making declaring objects difficult.
End note: mundus is the name of the project. It means universe (amongst other things) in Latin.