Re: defering the implementation of Base::instance() to Derived w/o link errors
reckless2k@yahoo.com wrote:
My simple client knows only about a Base Singleton and its interface;
but I need to be able to set the _instance static variable to a Derived
type to change the behavior of the client WITHOUT the client knowing
anything about Derived.
I wish I could defer the implementation of Base::instance() to
somewhere in Derived, but I need the definition of instance() to link
properly...
===================
Client side; knows nothing of Derived:
-------------------------------------
class Base { /* ... */ virtual void do_something(); };
#include "Base.h"
void main() { Base::instance()->do_something(); }
===================
Lib side; knows nothing of main():
-------------------------------------
#include "Base.h"
class Derived : public Base { /* ... */ void do_something(); };
===================
How can I set the _instance variable to be of type Derived* without
informing the client about Derived? I have tried setting _instance in
the ctor and createing a global Derived in Derived.cc, which forces the
type, but it is not dynamically allocated and it is not really a
singleton (I could create as many as I wanted and I would lose the
previous _instance values) I thought about setting the Base::_instance
value on the Lib side, but there is no guarantee for instantiation
order of statics in c++, so I didn't do it... there must be an easy way
to do this! I just can't see it. Any help would be greatly
appreciated.
When you are in the main, all the global variables had already been
instantiated. You'll have problems only if you use this 'do_something'
method in a constructor of a global variable.
In any case that you have problems with initialization of global
variables, you can switch to pointers and initialization routines that
apply constructors and set these pointers in the right order.
In your case you'll usually need a 'Base' ptr defined in the library
as a ptr to a 'Derived' object and imported by the client.
// common include file, e.g. interface.h, or even Base.h
extern Base * Base_interface; // defined in the library
// Lib.cc
// Attention! Two global variables are placed below
static Derived derived_interface;
// definition of the interface object
Base *Base_interface = &derived_interface;
In case that you need data for the constructor of Derived, you can
define the 'Base_interface' as 0, create a 'derived_interface' object
when you have the data in the lib (in some initialization function),
and put its address in 'Base_interface'.
// client side
// if (Base_interface) // in case that you're not sure that it exists
Base_interface->do_something();
Recall that in most cases you'll define some 'session' object for
interface with the library, and the interface objects can be easily
made a part of the session object.
Michael
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]