EDIT 2:
Here is a simple summary of what I want to do (I think):
I want to dynamically create global instances based on conditions that are calculated at run time.
You can skip to EDIT1 if you'd like to take a look at sample code, but at this point, the above bolded-text is probably the easiest to understand...
END EDIT 2.
My question is about polymorphism and inheritance. Specifically, I want to know if there is a way I could inherit functions and pointers from another class.
I have a class called Globals which contains various pointers to objects to other classes as well as various functions. Instead of copy/pasting code, I'll write up a simple example:
(I've removed header guards for simplicity and cleanliness)
The following is my globals.h and globals.cpp, respectively:
// Example of globals.h
#include <iostream>
#include <cstdio>
using namespace std;
class Globals {
public:
Globals ();
virtual ~Globals ();
void function1(char*);
void function2();
class Input *input;
class Error *error;
};
// Example of globals.cpp
#include "globals.h"
Globals::Globals()
{
input = new Input();
error = new Error();
}
void Globals::function1(char*nm)
{
cout << nm << endl;
}
Now, in my code for my Input class, say I want to use the function1(char*) method, would this be possible without passing an object to the Input class? What I mean by this is that I currently have my Input class being passed a *globals object, so then I could call the function like so: globals->function2();. But this can get very messy if I have a lot of functions within different classes. Additionally, is there a way I could use the Error pointer to object initialized in Globals? If Error had a function called error_func(), how could I be able to call it like so: error->error_func() from within my Input functions?
Thanks, and I apologize if I were too confusing in my question. I'll be happy to elaborate if needed.
Amit
EDIT 1: Added a simplified code to present what I want to do in a clearer way
// Example of globals.h
#include <iostream>
#include <cstdio>
#include "input.h"
#include "error.h"
using namespace std;
class Globals {
public:
Globals ();
virtual ~Globals ();
class Input *input;
class Error *error;
};
// Example of globals.cpp
#include "globals.h"
Globals::Globals()
{
input = new Input();
error = new Error();
}
// Example of input.h
#include "globals.h"
class Input {
public:
Input();
virtual ~Input();
}
// Example of input.cpp
#include "globals.h"
Input::Input()
{
error->print("Hello\n"); // <-- THIS is really what I want to accomplish (without being sent a globals object and say globals->error->print();
}
// Example of error.h
#include "globals.h"
class Error {
public:
Error() { }
virtual ~Error() { }
void print(char*);
}
// Example of error.cpp
#include "globals.h"
Error::print(char* nm)
{
cout << nm << endl;
}
If I'm understanding your question right, functions are automatically "inherited", at least for the purposes you need.
For example, your global class has two methods, function1(char*) and function2(). If you make a class:
class Descendent
: public Global
{ };
int main()
{
Global * global = new Global();
Global * desc = new Descendant();
char * str = "string";
// These two will run the same function:
global->function1(str);
desc->function1(str);
}
To prevent that (functions being called based on the current type), you must use virtual, like:
class Global
{
virtual void function1(char *);
};
class Descendant
{
virtual void function1(char *);
};
int main()
{
Global * global = new Global();
Global * desc = new Descendant();
char * str = "string";
// These two will NOT run the same function:
global->function1(str);
desc->function1(str);
}
Now, I'm not entirely sure, but the singleton idiom may be of use here, depending on just how global your Global is. In that case, you would have a global like:
class Global
{
static Global * GetSingleton()
{
if (!Global::m_Instance) Global::m_Instance = new Global();
return Global::m_Instance;
}
void function1(char *);
static Global * m_Instance;
};
class Descendant
{
void function1(char *)
{
Global * global = Global::GetGetSingleton();
// ...
}
};
There are a variety of ways to work with globals and functions being needed between classes. One of these may be it, depending on what exactly you're doing. If not, I'll try to edit and suggest one that does work.
I'm imagining you have a situation like this:
struct A {
void f();
};
struct B {
void g();
};
struct C : virtual A, virtual B {
C(A *ap, B *bp)
: A(ap), B(bp) // This doesn't actually work -- theoretical
{
}
void h()
{
f(); // calls A::f()
g(); // calls B::g();
}
};
Normally, when you create a C, you would be creating new As and Bs, but you would like to re-use existing ones instead, but still treat it like inheritance so that you don't have to explicitly specify which object to call.
Unfortunately, C++ doesn't support this. There are a couple of options:
You can make proxy classes that defer the function calls:
struct AProxy {
AProxy(A *ap) : a(*ap) { }
void f() { a.f(); }
A &a;
};
struct BProxy {
BProxy(B *bp) : b(*bp) { }
void g() { b.g(); }
B &b;
};
struct C : AProxy, BProxy {
C(A *ap,B *bp) : AProxy(ap), BProxy(bp) { }
void h()
{
f(); // calls AProxy::f() which calls a.f()
g(); // calls BProxy::g() which calls b.g()
}
};
This may help if you are using A's and B's in lots of different places.
If instead, you don't have many classes, but lots of calls to f() and g(), you might just do this:
struct C {
C(A *ap,B *bp) : a(*ap), b(*bp) { }
void f() { a.f(); }
void g() { b.g(); }
void h1()
{
f(); // well at least the call is clean here
g();
}
void h2()
{
f(); // and clean here
g();
}
A &a;
B &b;
};
If you don't have either of these cases, then just using the proper object each time like you were doing may be best.
Updated response:
Its sounds like what you want is actually the Factory pattern. I'm going to use logging as an example, where I assume that in one configuration you want to log and in another you might not want to:
// logger_interface.h
class LoggerInterface {
public:
virtual ~LoggerInterface() {}
virtual void Log(const string& message) = 0;
protected:
LoggerInterface() {}
};
The first step is to create a pure virtual interface representing the behavior that is configurable as in the example above. We will then create a factory function that can construct one based on configuration:
// logger_factory.h
LoggerInterface* CreateLogger(LoggerOptions options);
When implementing the factory, we keep the different implementations hidden:
// logger_factory.cc
class DoNotLogLogger : public LoggerInterface {
public:
DoNotLogLogger() {}
virtual ~DoNotLogLogger() {}
virtual void Log(const string& message) {}
};
class LogToStdErrLogger : public LoggerInterface {
public:
LogToStdErrLogger() {}
virtual ~LogToStdErrLogger() {}
virtual void Log(const string& message) {
std::cout << message << std::endl;
}
};
LoggerInterface* CreateLogger(LoggerOptions options) {
if (options.IsLoggingEnabled() && options.ShouldLogToStdErr()) {
return new LogToStdErrLogger;
}
return new DoNotLogLogger;
}
There is no reason why the object that you create dynamically in this way needs to be global; in fact, making it global is a really bad idea. Just create it where you need it, and pass it as a parameter to the functions that need it.
Original response:
Inheritance isn't the word you are looking for. Basically, what you are asking for is a static function:
class ClassName {
public:
static void methodName();
};
In the above, methodName can be invoked using ClassName::methodName() without requiring a specific instance of the class named ClassName. However, if you are to do this, it is more consistent with C++ style conventions to make it a freestanding function in a namespace like:
namespace name_of_namespace {
void functionName();
}
The above is invoked using name_of_namespace::functionName() as in the previous example, except with the benefit that it is easier to change or remove the prefix (e.g. via a using directive).
NOTE: from a design standpoint, you should only use a freestanding or static function if it does not rely on any state (other than the parameters passed to it) and there is no possibility of alternative implementations. As soon as there is state or alternative implementations, you really should pass around an object encapsulating this state, even if it is a pain to do, since passing around the object makes it easier to configure, makes it easier to mock-out in tests, and avoids threading issues.
Related
Is there any specific reason why I cannot override virtual method from base class with static one?
Anyone knows why it would be bad idea?
Example:
#include <cstdio>
class Foo
{
public:
virtual void SomeMethod() = 0;
};
class Bar : public Foo
{
public:
static void SomeMethod() override
{
printf("SomeMethod");
}
};
void SomeFunctionWithFoo( Foo *p )
{
p->SomeMethod();
}
int main()
{
Bar o;
o.SomeMethod();
SomeFunctionWithFoo( &o );
Bar::SomeMethod();
o.StaticSomeMethod();
}
Instead I have to do this:
#include <cstdio>
class Foo
{
public:
virtual void SomeMethod() = 0;
};
class Bar : public Foo
{
public:
void SomeMethod() override
{
StaticSomeMethod();
}
static void StaticSomeMethod()
{
printf("SomeMethod");
}
};
void SomeFunctionWithFoo( Foo *p )
{
p->SomeMethod();
}
int main()
{
Bar o;
o.SomeMethod();
SomeFunctionWithFoo( &o );
Bar::StaticSomeMethod();
o.StaticSomeMethod();
}
I think as long as you don't need to access member variables, your function can be static, so that it can serve behaviour without object. In the same time such static function can serve behaviour when using interface. But maybe I am wrong and I am missing something?
With one method and two classes, it is not problem, but I have case of 10 such methods inside class, and many classes that inherit.
In real world scenario, such possibility would make my code simpler.
Summary: member functions have an invisible first parameter that your static method doesn't have.
Details: Member functions (effectively) are effectively all static methods that have an "invisible" first parameter, which is the Bar* this parameter, which tells the method which instance of the class to use. So the signature of virtual void SomeMethod() is, under the covers, actually static void SomeMethod(Foo*), but static StaticSomeMethod() doesn't have the same number of parameters.
C++ is mostly able to pretend this parameter doesn't exist, but overrides are one case where it pops up. You also see it occur when trying to bind a member function to a std::function, where you have to explicitly pass the this as the first pointer.
I have a base class Base, with many derived classes (eg. Derived1, Derived2). Base has a pure virtual function fn, which is called many times using a Base pointer. Every time the function is called, I need to do some extra logging and related stuff. In particular, I use BOOST_CURRENT_FUNCTION in the derived-class functions to find out which function was called. Is there a way to know this information before calling the function, so that I do not have to rewrite the bookkeeping code in every derived function?
Edit: I wish to avoid writing __PRETTY_FUNCTION__ in each derived function.
#include <iostream>
using namespace std;
class Base {
public:
virtual void fn() = 0;
};
class Derived1:public Base {
public:
void fn() {
cout<<__PRETTY_FUNCTION__<<endl;
}
};
class Derived2:public Base {
public:
void fn() {
cout<<__PRETTY_FUNCTION__<<endl;
}
};
int main()
{
int choice =0;
Base *ptr1 = nullptr;
cout<<"Choose 0/1: "<<endl;
cin>>choice;
if(choice == 0) {
ptr1 = new Derived1;
}else {
ptr1 = new Derived2;
}
//********CAN I WRITE SOMETHING HERE, TO GIVE THE SAME RESULT?
ptr1->fn();
}
No, it cannot be. C++ does not support this kind of introspection. __PRETTY_FUNCTION__ is all you're gonna get.
From your description it seems you migth have a design issue. Have you considered using the template method design patter? The idea is to have your base class implement the common functionality and through virtual functions implement the specifics in your derived classes.
One idea is to implement the base pure virtual function and call it in each derived override. In the base one you increment a static counter. Something like:
#include <iostream>
#include <memory>
struct Base
{
static size_t counter;
virtual void f() = 0;
virtual ~Base() = default;
};
size_t Base::counter{0};
void Base::f() // IMPLEMENTATION, yes it's possible to implement a pure virtual function
{
++counter;
}
struct Derived1: Base
{
void f() override
{
Base::f(); // increment the counter
std::cout << "Derived1::f()\n";
}
};
struct Derived2: Base
{
void f() override
{
Base::f(); // increment the counter
std::cout << "Derived2::f()\n";
}
};
int main()
{
std::unique_ptr<Base> pBase1{new Derived1};
std::unique_ptr<Base> pBase2{new Derived2};
pBase1->f();
pBase1->f();
pBase2->f();
std::cout << Base::counter << std::endl; // outputs 3
}
Live on Wandbox
If I'm not wrong I believe this is an instance of the Template Method design pattern mentioned by #LordDosias. There is no other intrinsic way of getting this information out from the language, as C++ does not have genuine runtime reflection capabilities.
Well, aside from wrapping your macro in another macro that is smaller/shorter/does more, there is nothing that will provide the name of a function for you.
#define WHERE cout << __PRETTY_FUNCTION__ << endl
...
void fn() {
WHERE;
}
This also means you can turn on/off the tracing trivially:
#if TRACING
#define WHERE cout << __PRETTY_FUNCTION__ << endl
#else
#define WHERE
#endif
(You may want to wrap that in do { ... } while(0) in both sides to avoid problems if you were to put a WHERE inside an if, or some such, and still want it to work correctly when when it's "nothing")
The simplest answer is that, since C++ doesn't have auxiliary methods, you have to split the implementation of fn into a utility wrapper and the virtual function proper:
class Base {
protected:
virtual void fn_impl() = 0;
public:
void fn() { fn_impl(); }
};
class BaseWithLogging: public Base {
public:
void fn(); {
/* do logging */
fn_impl();
}
};
If you want the logs to capture the exact identity of the virtual (function name, file, line number, ...) which is actually, then there is no workaround for that; the boilerplate has to go into the function.
The crusty old preprocessor can be of help. E.g. simple-minded illustration:
#define LOG (cout<<__PRETTY_FUNCTION__<<endl)
and then you just have
LOG;
at the beginning of the function.
So basically I'm making buttons in a game, and the buttons are a called Button.
The class i want the function from to store is called SoccerLevelsClass. I've tried looking into function pointers, but I'm not sure what's going on though i think it's the correct thing to do.
I want to save the function of SoccerLevelsClass as a member of Button.
Would i do something like this?
//MenuButton.h
#ifndef MenuButton
#define MenuButton
....
class Button
{
public:
Button(void(*SoccerLevelsClass::func)());
void (*SoccerLevelsClass::function)();
....
}
#endif
//MenuButton.cpp
#include <MenuButton.h>
Button::Button(void(*SoccerLevelsClass::func)())
{
function=func; //something like this
}
I know the code is probably way off, but I'd like to know if anybody has any suggestions.
All i really want to know is if it's possible.
Yes, this can be done - either with function pointers like in your example, or with lambdas if you can use C++11.
However, since you want to call a bound function of another class, you would need to pass/store pointer to an instance of that class as well to do that, unless the function is static.
In C++11, this is trivial:
std::function<void(void)> _f;
void apply() {
_f();
}
Bar(void (Foo::* f)()) {
_f = std::bind(f, Foo());
}
In C++03, this is a little tricky. Note in both versions I construct a temporary to call the member function, but I'm not sure whether it is necessary to store an instance of the class.
#include <iostream>
#include <functional>
struct Foo
{
Foo() { }
void stuff() {
std::cout << "hi\n";
}
};
struct Bar
{
void (Foo::* _f)();
void apply() {
(Foo().*_f)();
}
Bar(void (Foo::* f)()) {
_f = f;
}
};
int main()
{
Bar bar(&Foo::stuff);
bar.apply();
}
For what you are trying to do I would use the observer pattern:
class IFootballObserver
{
public:
virtual void OnBallKicked() = 0;
virtual ~IFootballObserver() {}
};
class Fooball
{
public:
Fooball(IFootballObserver& obs)
: mObs(obs)
{
// Call the observer interface at any time like so:
mObs.OnBallKicked();
}
private:
IFootballObserver& mObs;
};
class Button : public IFootballObserver
{
public:
// Football could be passed in/owned by something else
Button() : mFootball(*this) { }
void DoSomething()
{
// Called when foot ball is kicked
}
private:
virtual void OnBallKicked()
{
DoSomething();
}
Fooball mFootball;
};
I find this easier than using function pointers/std::function. Plus you could have a vector of observers and notify many objects of events.
I was wondering whether there's a way to override a function for a specific instance only. For ex,
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
Is there a way to achieve this?
I think virtual function is just what you want, with virtual function, different instances of the same type can have different functions, but you need to inherit the base class. for example
class A
{
public:
...
virtual void update()
{
std::cout << "Class A\n";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class B\n";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class C\n";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
each instance in the above code will bind different update functions.
Besides, you can also use function pointer to implement your requirement, but it is not recommended. For example
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update A\n";
}
void b_update()
{
std::cout << "update B\n";
}
void c_update()
{
std::cout << "update C\n";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
Hope helps!
Hold a function in the class.
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
You may have noticed that the end brace of a class is often followed by a semicolon, whereas the end braces of functions, while loops etc don't. There's a reason for this, which relates to a feature of struct in C. Because a class is almost identical to a struct, this feature exists for C++ classes too.
Basically, a struct in C may declare a named instance instead of (or as well as) a named "type" (scare quotes because a struct type in C isn't a valid type name in itself). A C++ class can therefore do the same thing, though AFAIK there may be severe limitations on what else that class can do.
I'm not in a position to check at the moment, and it's certainly not something I remember using, but that may mean you can declare a named class instance inheriting from a base class without giving it a class name. There will still be a derived type, but it will be anonymous.
If valid at all, it should look something like...
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
Personally, even if this is valid, I'd avoid using it for a number of reasons. For example, the lack of a class name means that it's not possible to define member functions separately. That means that the whole class declaration and definition must go where you want the instance declared - a lot of clutter to drop in the middle of a function, or even in a list of global variables.
With no class name, there's presumably no way to declare a constructor or destructor. And if you have non-default constructors from the base class, AFAIK there's no way to specify constructor parameters with this.
And as I said, I haven't checked this - that syntax may well be illegal as well as ugly.
Some more practical approaches to varying behaviour per-instance include...
Using dependency injection - e.g. providing a function pointer or class instance (or lambda) for some part of the behavior as a constructor parameter.
Using a template class - effectively compile-time dependency injection, with the dependency provided as a function parameter to the template.
I think it will be the best if you'll tell us why do you need to override a function for a specific instance.
But here's another approach: Strategy pattern.
Your class need a member that represent some behaviour. So you're creating some abstract class that will be an interface for different behaviours, then you'll implement different behaviours in subclasses of that abstract class. So you can choose those behaviours for any object at any time.
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
You can use local classes, yet, personally, I consider the "hold function in the class" approach mentioned in the other answer better. I'd recommend the following approach only if doFunc must access internals of your base class, which is not possible from a function held in a member variable:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
From a design patterns point of view, the "local classes" approach implements the template method pattern, while the "hold a function(al) in a member variable" approach reflects the strategy pattern. Which one is more appropriate depends on what you need to achieve.
I need several C++ classes to have a static method "register", however the implementation of register varies between those classes.
It should be static because my idea is to "register" all those classes with Lua (only once of course).
Obviously I can't declare an interface with a static pure virtual function. What do you guys suggest me to do ? Simplicity is welcome, but I think some kind of template could work.
Example of what I would like to achieve
class registerInterface
{
public:
static virtual void register() = 0; //obviously illegal
};
class someClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua
}
}
class someOtherClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua in a different way
}
}
int main()
{
someClass::register();
someOtherClass::register();
return 0;
}
Based on how you've described the problem, it's unclear to me why you even need the 'virtual static method' on the classes. This should be perfectly legal.
class SomeClass {
static void register(void) {
...
}
}
class SomeOtherClass {
static void register(void) {
...
}
}
int main(int argc, char* argv[]) {
SomeClass::register();
SomeOtherClass::register();
return 0;
}
Drop the RegisterInterface, I don't think you need it.
If it helps, you could take Hitesh's answer, and add:
struct luaRegisterManager {
template <typename T>
void registrate() {
T::registrate();
// do something else to record the fact that we've registered -
// perhaps "registrate" should be returning some object to help with that
}
};
Then:
int main() {
luaRegisterManager lrm;
lrm.registrate<someClass>();
lrm.registrate<someOtherClass>();
}
More generally, if you want to introduce any dynamic polymorphism in C++, then you need an object, not just a class. So again, perhaps the various register functions should be returning objects, with some common interface base class registeredClass, or classRegistrationInfo, or something along those lines.
Could provide an example of what you feel it is that you need dynamic polymorphism for? Hitesh's code precisely matches your one example, as far as I can see, so that example must not cover all of your anticipated use cases. If you write the code that would be using it, perhaps it will become clear to you how to implement it, or perhaps someone can advise.
Something else that might help:
#include <iostream>
#include <string>
#include <vector>
struct Registered {
virtual std::string name() = 0;
virtual ~Registered() {}
Registered() {
all.push_back(this);
}
static std::vector<Registered*> all;
};
std::vector<Registered*> Registered::all;
typedef std::vector<Registered*>::iterator Iter;
template <typename T>
struct RegisteredT : Registered {
std::string n;
RegisteredT(const std::string &name) : n(name) { T::registrate(); }
std::string name() { return n; }
// other functions here could be implemented in terms of calls to static
// functions of T.
};
struct someClass {
static Registered *r;
static void registrate() { std::cout << "registering someClass\n"; }
};
Registered *someClass::r = new RegisteredT<someClass>("someClass");
struct someOtherClass {
static Registered *r;
static void registrate() { std::cout << "registering someOtherClass\n"; }
};
Registered *someOtherClass::r = new RegisteredT<someOtherClass>("someOtherClass");
int main() {
for (Iter it = Registered::all.begin(); it < Registered::all.end(); ++it) {
std::cout << (*it)->name() << "\n";
}
}
There are all sorts of problems with this code if you try to split it across multiple compilation units. Furthermore, this kind of thing leads to spurious reports from memory leak detectors unless you also write some code to tear everything down at the end, or use a vector of shared_ptr, Boost pointer vector, etc. But you see the general idea that a class can "register itself", and that you need an object to make virtual calls.
In C++ you usually try to avoid static initialisation, though, in favour of some sort of setup / dependency injection at the start of your program. So normally you would just list all the classes you care about (calling a function on each one) rather than try to do this automatically.
Your intentions are noble, but your solution is inkling towards "overengineering" (unless I am missing an obvious solution).
Here is one possibility: You can use the Virtual Friend function idiom For example,
class RegisterInterface{
friend void register(RegisterInterface* x){x->do_real_register();}
protected:
virtual void do_real_register();
}
class Foo : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
class Bar : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
int main(int argc, char* argv[]) {
BOOST_FOREACH(RegisterInterface* ri, registered_interfaces)
{
register(ri);
}
return 0;
}
I know you've already accepted an answer, but I figured I would write this up anyway. You can have self-registering classes if you use some static initialization and the CRTP:
#include <vector>
#include <iostream>
using namespace std;
class RegisterableRoot // Holds the list of functions to call, doesn't actually need
// need to be a class, could just be a collection of globals
{
public:
typedef void (*registration_func)();
protected:
static std::vector<registration_func> s_registery;
public:
static void do_registration()
{
for(int i = 0; i < s_registery.size(); ++i)
s_registery[i]();
}
static bool add_func(registration_func func) // returns something so we can use it in
// in an initializer
{
s_registery.push_back(func);
return true;
}
};
template<typename RegisterableType> // Doesn't really need to inherit from
class Registerable : public RegisterableRoot // RegisterableRoot
{
protected:
static const bool s_effect;
};
class A : public Registerable<A> // Honestly, neither does A need to inherit from
// Registerable<T>
{
public:
static void Register()
{
cout << "A" << endl;
}
};
class B : public Registerable<B>
{
public:
static void Register()
{
cout << "B" << endl;
}
};
int main()
{
RegisterableRoot::do_registration();
return 0;
}
std::vector<RegisterableRoot::registration_func> RegisterableRoot::s_registery;
template <typename RegisterableType> // This is the "cute" part, we initialize the
// static s_effect so we build the list "magically"
const bool Registerable<RegisterableType>::s_effect = add_func(&RegisterableType::Register);
template class Registerable<A>; // Explicitly instantiate the template
// causes the equivalent of
// s_registery.push_back(&A::Register) to
// be executed
template class Registerable<B>;
This outputs
A
B
although I wouldn't rely on this order if I were you. Note that the template class Registerable<X> need not be in the same translation unit as the call to do_registration, you can put it with the rest of your definition of Foo. If you inherit from Registerable<> and you don't write a static void Register() function for your class you'll get a (admittedly probably cryptic) compiler error much like you might expect if there really was such a thing as "static virtuals". The "magic" merely adds the class specific function to the list to be called, this avoids several of the pitfalls of doing the actual registration in a static initializer. You still have to call do_registration for anything to happen.
How about this way? Define an interface class:
// IFoobar.h
class IFoobar{
public:
virtual void Register(void) = 0;
}
Then define the class that handles the register..
// RegisterFoobar.h
class RegisterFoobar{
public:
// Constructors etc...
IFoobar* fooBar;
static void RegisterFoobar(IFoobar& fubar){
foobar = &fubar;
}
private:
void Raise(void){ foobar->Register(); }
}
Now, then define another class like this
// MyFuBar.h
class MyFuBar : IFoobar{
public:
// Constructors etc...
void Register(void);
private:
RegisterFoobar* _regFoobar;
}
Call the code like this:
//MyFuBar.cpp
MyFuBar::MyFuBar(){
_regFoobar = new Foobar();
_regFoobar->RegisterFoobar(this);
}
void MyFuBar::Register(void){
// Raised here...
}
Maybe I have misunderstood your requirements...