Subclass as argument in superclass's member function, C++ - c++

I'm new to OOP and I'm working on a C++ project. I isolated my problem to make answering easy but here's the real scenario:
I have a superclass member function, that modifies values inside the object that called it. The modification is based on a value coming from another object of the same class. This object is given to the function as the only parameter. Such as:
void BaseClass::function(BaseClass x) {}
However, I created a subclass. And if the parameter is a subclass type, I want to modify its unique attribute, too.
void BaseClass::function(DerivedClass x) {}
The problem is that the subclass is obviously defined later in the code.
I don't want it as two separate methods, because the calculation algorithm is already written inside, and also the solution I search for doesn't require to change the code at the places where the function is already in use. Besides, every other possibility that comes to mind (e.g. using typeid()) looks silly.
#include <iostream>
#include <string>
class Base
{
protected:
//common attribute
const std::string name;
public:
//constructor for common attribute
Base(const std::string nameString) : name(nameString) {}
//getter
std::string getName() { return name; }
//superclass as parameter
void test1(Base &example) { std::cout << example.getName(); }
//subclass as parameter (I'd want the line below to work)
//void test2(Derived &example) { std::cout << example.getNumber(); }
};
class Derived : private Base
{
protected:
//unique attribute
const std::string number;
public:
//constructor
Derived(const std::string nameString, const std::string numberString) : Base(nameString),
number(numberString) {}
//getter for unique attribute
std::string getNumber() { return number; }
};
int main ()
{
Base object = Base("whatever");
Base baseParameter = Base("base");
Derived derivedParameter = Derived("derived", "12");
object.test1(baseParameter);
//object.test2(derivedParameter);
return 0;
}
What is the standard way of doing it?

You could make test2 a template, and ensure that it's only used with types derived from Base:
template<typename Derived>
void test2(Derived &example)
{
static_assert(std::is_base_of_v<Base, Derived>);
std::cout << example.getNumber();
}
Here's a demo.

Related

Access function from another class without having any relations

I'm still new to C++ and I'm trying to know if it is possible to access a function from another class knowing that no one is the father class here . This is a piece of my program to show you what I want to do exactly .
class CSubject
{
public:
CSubject() = default;
CSubject(std::string m_Name){this->Name = m_Name;}
void print(){ std::cout << Name;}
~CSubject(){}
private:
std::string Name;
};
class CStudent
{
public:
CStudent() = default;
void Method2()
{
//Call the print method and print the name "test"
}
~CStudent(){}
private:
};
int main()
{
CSubject AE("test");
CStudent ST;
ST.Method2(); //Print test;
return 0;
}
Forget about classes for a second. You want to call Method2(), and from there, print information that was put into the AE. Suppose you didn't have two classes of your own, but rather, say:
void Method2();
int main() {
const char* AE = "Test";
// ...
Method2();
}
That wouldn't work, right? And it shouldn't work, because local variables in a function (like main()) are usable only within that function's body; that's their local scope. For Method2() to use AE in any way, you have to let Method2() "know" about it. It's the same with classes.
You could use static method and attributes, which can be altered by creating an instance and overwriting it and also getting them from unrelated processes.
I would edit your CSubject class like this:
class CSubject {
public:
CSubject() = default;
CSubject(std::string m_Name) {
CSubject::Name = m_Name;
}
static void print() {
if (CSubject::Name.empty()) //checking is a good practice
std::cout << "The name is empty...\n";
else
std::cout << Name;
}
~CSubject() {}
private:
static std::string Name;
};
And you could access the print method from your Method2 like this:
void Method2() {
CSubject::print();
}
But beware! The static attribute is the only one for the class. If you plan on creating multiple CSubject instances and their new names, then you could store the m_Name attribute as non-static private, print() as non-static public, and Method2 should have a parameter where you pass the CSubject (the whole object or just the data that you need) that is in your interest.

Polymorphism and function binding

For an event system i'm writing i want to bind callbacks to a list of functions.
Here is a basic example of what i want to do:
#include <iostream>
#include <functional>
#include <string>
class Base {
public:
virtual std::string getType() const = 0;
};
class Derived : public Base {
protected:
int some_data;
public:
Derived(int some_data): some_data(some_data) {}
virtual std::string getType() const {
return "Derived";
}
int getData() const {
return this->some_data;
}
};
class DerivedTwo : public Base {
protected:
double some_data;
public:
DerivedTwo(double some_data): some_data(some_data) {}
virtual std::string getType() const {
return "DerivedTwo";
}
// The type of data is not always the same.
double getData() const {
return this->some_data;
}
};
// The type of member should ALWAYS be Derived but then i can't store it in <callback>
void onDerivedEvent(Base& member) {
std::cout << member.getType() << std::endl;
// This is obviously not possible with member being a base class object
// member.getData();
}
// The type of member should ALWAYS be DerivedTwo but then i can't store it in <callback>
void onDerivedTwoEvent(Base& member) {
std::cout << member.getType() << std::endl;
}
int main() {
std::function<void(Base&)> callback;
callback = std::bind(onDerivedEvent, std::placeholders::_1);
callback(Derived(2));
callback = std::bind(onDerivedTwoEvent, std::placeholders::_1);
callback(DerivedTwo(3.0));
return 0;
}
The only thing i would like to change is that onCallback() should take a derived class member as argument instead of a reference to a base object, so i can call getData() for example.
In this example this would mean:
void onCallback(Derived& derived);
However, if i do this, i can no longer bind() the method to callback because the argument types are not matching.
Does anyone know how to make this work?
// EDIT
Sorry for the confusion here, i updated the source code with some more specifics and examples to maybe clarify what im doing here.
Note:
Since it seems like this is very relevant, here is the specific use case for what i'm trying to do here:
It's part of an event system for an engine i'm building. There are basic events pre-defined but it should be extendable with more specific events by a user using this engine. So there is not definitive list of derived classes. Then some object can subscribe to a specific event type and whenever the central event bus recieves such an event, it calls all subscribed callback functions with the event as argument. The reason i am not adding a one and for all handle function in the derived class is, the events an be used in multiple ways.
Answers to some questions from the comments:
What should happen if you pass onCallback an object that isn't that specific Derived&? (ie, add a Derived2 which has a doStuff2. Pass it to callback. What do you want to happen?
That should not be possible.
I might have not calrified that and also had a misleading information at the beginning which i have editted since then. The type of the passed derived class is always known beforehand. For example: onKeyEvent will always recieve a KeyEvent object and not a base class object or any other derived variants.
However, the variable to which this function is bound should be able to store functions which accept different derived classes from Base
This is my storage for all events:
std::map<EventType, std::list<std::function<void(const Event&)>>> listener_map;
Why isn't onCallback a method in Base that Derived overrides
I answered this in a comment. ...The reason i am not adding a one and for all handle function in the derived class is, the events an be used in multiple ways...
Meaning, i might have an KeyEvent which has the data to a key (which key, is it pressed/released/held) and the listening function(s) can use this data for whatever it wants. (Check if some specific key is pressed, chech if any random key is pressed and so on.) Some other events might not have any data at all and just notify a listener that something happened or have multiple sets of data etc.
Is there, or can there be, a finite, bounded at compile time, central list of all of the types that derive from Base at any point in your code?
In theory yes. During compilation there will be a finite number of Derived classes. However these might be different for the compilation of the library and the compilation of the project using this library.
template<class Base>
struct poly_callback {
template<class T>
static poly_callback make( std::function<void(T&)> f ) {
return { std::function<void(void*)>( [f]( void* ptr ) { f(*static_cast<T*>(static_cast<Base*>(ptr))); }) };
}
template<class T>
poly_callback( void(*pf)(T&) ):poly_callback( make<T>( pf ) ) {}
poly_callback( poly_callback const& ) = default;
poly_callback( poly_callback && ) = default;
void operator()( Base& b ) {
return type_erased( static_cast<void*>(std::addressof(b)) );
}
private:
std::function<void(void*)> type_erased;
poly_callback( std::function<void(void*)> t ):type_erased(std::move(t)) {}
};
A poly_callback<Event> can store a callable with signature compatible to void(Derived&), where Derived is derived from Event. It must be called with exactly an instance of the Derived& type or undefined behavior results as it blindly downcasts.
Stop using std::bind, it is functionally obsolete.
class Base {
public:
virtual std::string getType() const = 0;
};
class Derived : public Base {
protected:
int some_data;
public:
Derived(int some_data): some_data(some_data) {}
virtual std::string getType() const {
return "Derived";
}
int getData() const {
return this->some_data;
}
};
class DerivedTwo : public Base {
protected:
double some_data;
public:
DerivedTwo(double some_data): some_data(some_data) {}
virtual std::string getType() const {
return "DerivedTwo";
}
// The type of data is not always the same.
double getData() const {
return this->some_data;
}
};
// The type of member should ALWAYS be Derived but then i can't store it in <callback>
void onDerivedEvent(Derived& member) {
std::cout << member.getType() << "\n";
std::cout << member.getData() << "\n";
}
// The type of member should ALWAYS be DerivedTwo but then i can't store it in <callback>
void onDerivedTwoEvent(DerivedTwo& member) {
std::cout << member.getType() << "\n";
std::cout << member.getData() << "\n";
}
struct callbacks {
std::unordered_map< std::string, std::vector< poly_callback<Base> > > events;
void invoke( std::string const& name, Base& item ) {
auto it = events.find(name);
if (it == events.end())
return;
for (auto&& f : it->second)
f( item );
}
template<class Derived>
void connect( std::string const& name, void(*pf)(Derived&) )
{
events[name].push_back( pf );
}
template<class Derived>
void connect_T( std::string const& name, std::function<void(Derived&)> f )
{
events[name].push_back( std::move(f) );
}
};
int main() {
callbacks cb;
cb.connect("one", onDerivedEvent );
cb.connect("two", onDerivedTwoEvent );
Derived d(7);
DerivedTwo d2(3.14);
cb.invoke( "one", d );
cb.invoke( "two", d2 );
return 0;
}
Live example.
This can be tweaked for safety and usability. For example, check that the typeid actually matches.
Output is:
Derived
7
DerivedTwo
3.14
and as you can see, the callback functions take Derived& and DerivedTwo& objects.
In my experience this is a bad plan.
Instead, have a broadcaster<KeyboardEvent> keyboard; and don't look up your event registry systems with strings.
A map from string-to-callback only makes sense if there is some way to treat the callbacks uniformly. And you don't want to treat these callbacks uniformly. Even if you chose to store them uniformly for efficiency sake (useful in ridiculously huge frameworks), I'd want type-safe APIs not a map.

Overwrite Base Class Member with New Type

I'm trying to use C++ to emulate something like dynamic typing. I'm approaching the problem with inherited classes. For example, a function could be defined as
BaseClass* myFunction(int what) {
if (what == 1) {
return new DerivedClass1();
} else if (what == 2) {
return new DerivedClass2();
}
}
The base class and each derived class would have the same members, but of different types. For example, BaseClass may have int xyz = 0 (denoting nothing), DerivedClass1 might have double xyz = 123.456, and DerivedClass2 might have bool xyz = true. Then, I could create functions that returned one type but in reality returned several different types. The problem is, when ere I try to do this, I always access the base class's version of xyz. I've tried using pointers (void* for the base, and "correct" ones for the derived classes), but then every time I want to access the member, I have to do something like *(double*)(obj->xyz) which ends up being very messy and unreadable.
Here's an outline of my code:
#include <iostream>
using std::cout;
using std::endl;
class Foo {
public:
Foo() {};
void* member;
};
class Bar : public Foo {
public:
Bar() {
member = new double(123.456); // Make member a double
};
};
int main(int argc, char* args[]) {
Foo* obj = new Bar;
cout << *(double*)(obj->member);
return 0;
};
I guess what I'm trying to ask is, is this "good" coding practice? If not, is there a different approach to functions that return multiple types or accept multiple types?
That is not actually the way to do it.
There are two typical ways to implement something akin to dynamic typing in C++:
the Object-Oriented way: a class hierarchy and the Visitor pattern
the Functional-Programming way: a tagged union
The latter is rather simple using boost::variant, the former is well documented on the web. I would personally recommend boost::variant to start with.
If you want to go down the full dynamic typing road, then things get trickier. In dynamic typing, an object is generally represented as a dictionary containing both other objects and functions, and a function takes a list/dictionary of objects and returns a list/dictionary of objects. Modelling it in C++ is feasible, but it'll be wordy...
How is an object represented in a dynamically typed language ?
The more generic representation is for the language to represent an object as both a set of values (usually named) and a set of methods (named as well). A simplified representation looks like:
struct Object {
using ObjectPtr = std::shared_ptr<Object>;
using ObjectList = std::vector<ObjectPtr>;
using Method = std::function<ObjectList(ObjectList const&)>;
std::map<std::string, ObjectPtr> values;
std::map<std::string, Method> methods;
};
If we take Python as an example, we realize we are missing a couple things:
We cannot implement getattr for example, because ObjectPtr is a different type from Method
This is a recursive implementation, but without the basis: we are lacking innate types (typically Bool, Integer, String, ...)
Dealing with the first issue is relatively easy, we transform our object to be able to become callable:
class Object {
public:
using ObjectPtr = std::shared_ptr<Object>;
using ObjectList = std::vector<ObjectPtr>;
using Method = std::function<ObjectList(ObjectList const&)>;
virtual ~Object() {}
//
// Attributes
//
virtual bool hasattr(std::string const& name) {
throw std::runtime_error("hasattr not implemented");
}
virtual ObjectPtr getattr(std::string const&) {
throw std::runtime_error("gettattr not implemented");
}
virtual void setattr(std::string const&, ObjectPtr) {
throw std::runtime_error("settattr not implemented");
}
//
// Callable
//
virtual ObjectList call(ObjectList const&) {
throw std::runtime_error("call not implemented");
}
virtual void setcall(Method) {
throw std::runtime_error("setcall not implemented");
}
}; // class Object
class GenericObject: public Object {
public:
//
// Attributes
//
virtual bool hasattr(std::string const& name) override {
return values.count(name) > 0;
}
virtual ObjectPtr getattr(std::string const& name) override {
auto const it = values.find(name);
if (it == values.end) {
throw std::runtime_error("Unknown attribute");
}
return it->second;
}
virtual void setattr(std::string const& name, ObjectPtr object) override {
values[name] = std::move(object);
}
//
// Callable
//
virtual ObjectList call(ObjectList const& arguments) override {
if (not method) { throw std::runtime_error("call not implemented"); }
return method(arguments);
}
virtual void setcall(Method m) {
method = std::move(m);
}
private:
std::map<std::string, ObjectPtr> values;
Method method;
}; // class GenericObject
And dealing with the second issue requires seeding the recursion:
class BoolObject final: public Object {
public:
static BoolObject const True = BoolObject{true};
static BoolObject const False = BoolObject{false};
bool value;
}; // class BoolObject
class IntegerObject final: public Object {
public:
int value;
}; // class IntegerObject
class StringObject final: public Object {
public:
std::string value;
}; // class StringObject
And now you need to add capabilities, such as value comparison.
You can try the following design:
#include <iostream>
using std::cout;
using std::endl;
template<typename T>
class Foo {
public:
Foo() {};
virtual T& member() = 0;
};
class Bar : public Foo<double> {
public:
Bar() : member_(123.456) {
};
virtual double& member() { return member_; }
private:
double member_;
};
int main(int argc, char* args[]) {
Foo<double>* obj = new Bar;
cout << obj->member();
return 0;
};
But as a consequence the Foo class already needs to be specialized and isn't a container for any type anymore.
Other ways to do so, are e.g. using a boost::any in the base class
If you need a dynamic solution you should stick to using void* and size or boost::any. Also you need to pass around some type information as integer code or string so that you can decode the actual type of the content.
See also property design pattern.
For example, you can have a look at zeromq socket options https://github.com/zeromq/libzmq/blob/master/src/options.cpp

How to make a member function in an inheritance hierarchy return always the same value?

I have an inheritance hierarchy and I want to make each class in this hierarchy have a set of attributes which are particular for that class and which do not change during the run of the program. For example:
class Base
{
public:
const std::string getName() const;
bool getAttribute1() const;
int getAttribute2() const;
};
Now I want these functions to return the same result all the time. Furthermore, when another class inherits Base this class should have its own set of attributes and any instance of this derived class should have the same attributes. Also the name should be unique for each class.
I want to know a way to make this as transparent and elegant as possible. Sofar I have considered 2 ideas that I can use:
Make some lock system.
That is provide setters for these attributes, but make them throw a runtime exception when they are called more than once.
Make the getters pure virtual.
In this case, the result of the functions would not be stored inside the object itself. This would make it vaguely clear that the result depends on the dynamic type.
Both ideas sound incredibly lousy, so I need your help.
I am new to C++, but I know there are a lot of idioms and patterns to solve general problems like this one. Do you know any?
I have an inheritance hierarchy and I want to make each class in this hierarchy have a set of attributes which are particular for that class and which do not change during the run of the program
Well, then just provide the corresponding values as arguments to a class constructor, and do not expose any setter method on the public interface. This will make sure the values remain constant throughout the life-time of the object.
To protect against possible errors that would alter the value of those data members from member functions of your class (which of course can access the private data), make those data members const. Notice, that this will force you to initialize those members in the constructor's initializer list.
class Base
{
public:
// Forwarding constructor (requires C++11)
Base() : Base("base", true, 42) { }
const std::string getName() const { return _s; }
bool getAttribute1() const { return _a1; }
int getAttribute2() const { return _a2; }
protected:
// Constructor that can be called by derived classes
Base(std::string s, bool a1, int a2)
: _s(s), _a1(a1), _a2(a2) { }
private:
const std::string _s;
const bool _a1;
const bool _a2;
};
Derived classes would then just construct the base subobject with the appropriate arguments:
class Derived : public Base
{
public:
// Provide the values for the constant data members to the base constructor
Derived() : Base("derived", false, 1729) { }
};
This way you would not incur in the overhead of a virtual function call, and you won't have to rewrite similar virtual functions for each of these members in derived classes.
Make them virtual and hard-code the result which the functions should return:
class Base
{
public:
virtual const std::string getName() const { return "BaseName"; }
virtual bool getAttribute1() const { return whatEverAttributeValueYouWant; }
virtual int getAttribute2() const { return attributeValueHere; }
};
class Derived : public Base {
public:
virtual const std::string getName() const { return "DerivedName"; }
virtual bool getAttribute1() const { return whatEverOtherAttributeValueYouWant; }
virtual int getAttribute2() const { return otherAttributeValueHere; }
};
If you want to describe classes rather than objects, use (kind-of) traits:
template<class T> struct AttributeValues;
template<> struct AttributeValues<Base> {
static const std::string name () { return "BaseName"; }
};
template<> struct AttributeValues<Derived> {
static const std::string name () { return "DerivedName"; }
};
//...
auto nameBase = AttributeValues<Base>::name ();
auto nameDerived = AttributeValues<Derived>::name ();

Several C++ classes need to use the same static method with a different implementation

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...