Can't Implement Method in Subnamespace For Derived Class - c++

Dotnet dev with embedded C experience here moving into cpp land to give you an idea of my experience/knowledge.
I've got a base class Window in src/Core/Window/:
namespace Pyrite::Core::Window
{
class PYR_API Window
{
public:
using EventCallbackFn = std::function<void(Pyrite::Event&)>;
virtual ~Window();
virtual void OnUpdate();
virtual uint32_t GetWidth() const = 0;
virtual uint32_t GetHeight() const = 0;
virtual void SetEventCallback(const EventCallbackFn& callback) = 0;
virtual void SetVSync(bool isEnabled) = 0;
virtual bool IsVSyncEnabled() const = 0;
static Window* Create(const WindowProperties& props = WindowProperties());
};
}
From this, I have created a derived class for the platform-specific WindowsWindow, I want to store this in src/Core/Window/Platform/:
namespace Pyrite::Core::Window::Platform
{
class WindowsWindow : public Pyrite::Core::Window::Window
{
public:
WindowsWindow(const WindowProperties& properties);
virtual ~WindowsWindow();
void OnUpdate() override;
inline uint32_t GetWidth() const override { return m_Data.Width; }
inline uint32_t GetHeight() const override { return m_Data.Height; }
inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; }
void SetVSync(bool isEnabled) override { m_Data.VSyncEnabled = isEnabled; }
bool IsVSyncEnabled() override {return m_Data.VSyncEnabled; }
private:
virtual void Init(const WindowProperties& properties);
virtual void Close();
GLFWwindow* m_Window;
struct WindowData
{
std::string Title;
uint32_t Width, Height;
bool VSyncEnabled;
EventCallbackFn EventCallback;
};
WindowData m_Data;
};
}
However, in WindowsWindow.cpp, when I try to create my implementation for Window::Create() I get an error about not being able to define it here:
namespace Pyrite::Core::Window::Platform
{
static bool s_GLFWInitialised = false;
Window* Window::Create(const WindowProperties& properties)
{
return new WindowsWindow(properties);
}
}
'Pyrite::Core::Window::Window *Pyrite::Core::Window::Window::Create(const Pyrite::Core::Window::WindowProperties &)': symbol cannot be defined within namespace 'Platform' PyriteEngine C:\repos\Pyrite\PyriteEngine\src\Core\Window\Platform\WIndowsWindow.cpp 9
When I adjust the namespaces so they're all sat in Pyrite::Core::Window it seems to go away... However, it seems odd to me that I can't define this in the subnamespace. I want my namespaces to follow my folder structure if possible (as that's pretty much what I'm used to and it keeps things logical and uncluttered) and hiding the platform specific stuff away in a subnamespace seems to make sense to me.
Is this just something I flat out can't do or am I missing something here?

First, the separation between source files and namespaces in C++ is a feature in that they can follow the same structure if appropriate but other organizations are also possible. Beyond that, it’s impossible to do (literally) what you ask, because it produces weird “siblings” for name lookup that are considered to be more trouble than they’re worth. In particular, given
namespace A {
int i;
struct X {void f(); void g(); void h();};
namespace B {
void g();
namespace C {
int i;
void h();
void X::f() {g(); h(); ++i;} // pretend this is OK
}
}
}
it’s not entirely clear whether B::g and/or C::h are “closer” to the definition of X::f than X::g or X::h. It’s also not clear that it’s desirable to have moving X::f’s definition into or out of the class change which i is found.
You can often use using-declarations to work around these limitations: X above might be defined in B but then exposed in A (or in C!). Sometimes the affected member functions can alternatively be moved into a base class that belongs to a different namespace.

Related

How to prevent undefined references to internal functions of my API

I have created a C++ module which has an API part and an internal part. The API contains a long (more then 30) list of polymorphic classes inheriting directly or indirectly from the same baseclass. In my internal classes/functions these classes are used differently, so I moved some functionality to these classes to be used polimorphically. These functionalites depend on some internal resources, while the internal functions depend on these classes so I broke this circular dependency by forward declaring the necessary classes in the .h files and including them in the .cpp files. This way my module compiles and works perfectly.
Here comes the problem. When I include the API from another module, I get "undefined reference to ...." errors to internal functions in the API classes polimorphic functions. I think this is due to the forward declarations. These internal classes are never defined in the eyes of the second module which uses the API.
Broadly my module looks like this:
InternalClass.h:
class ApiObjBase;
class InternalClass {
public:
static InternalClass& get(); // singleton
void processApiObjBase(ApiObjBase& apiObj);
static const Resource& getResource1();
static const Resource& getResource2();
static const std::map<uint64_t, std::unique_ptr<ApiObjBase>>& getApiObjStorage();
UacManager(const UacManager&) = delete; // singleton
UacManager& operator=(const UacManager&) = delete; // singleton
private:
InternalClass(); // singleton
Resource resource1;
Resource resource2;
std::map<uint64_t, std::unique_ptr<ApiObjBase>> ApiObjStorage;
}
InternalClass.cpp:
#include "ApiObjBase.h"
void InternalClass::processApiObjBase(ApiObjBase& apiObj) {
apiObj.internalPolyFunc1();
apiObj.internalPolyFunc2();
// ...
}
const Resource& InternalClass::getResource1() {
return get().resource1;
}
const Resource& InternalClass::getResource2() {
return get().resource2;
}
// Other implementations of member functions ...
ApiObjBase.h:
class InternalClass;
class ApiObjBase {
protected:
int internalVariable1;
int internalVariable2;
int apiVariable1;
int apiVariable2;
public:
ApiObjBase() = default;
// getters, setters
void internalPolyFunc1() = 0;
void internalPolyFunc2() = 0;
void apiPolyFunc1() = 0;
void apiPolyFunc2() = 0;
}
ApiObjBase.cpp:
#include "ApiObjBase.h"
// ...
ApiObjDerived1.h:
#include "ApiObjBase.h"
class ApiObjDerived1 : public ApiObjBase {
protected:
int internalVariable3;
int internalVariable4;
int apiVariable3;
int apiVariable4;
public:
ApiObjDerived1() = default;
// getters, setters
void internalPolyFunc1() override;
void internalPolyFunc2() override;
void apiPolyFunc1() override;
void apiPolyFunc2() override;
}
ApiObjDerived1.cpp:
#include "ApiObjDerived1.h"
#include "InternalClass.h"
void ApiObjDerived1::internalPolyFunc1() {
Resource& res = InternalClass::getResource1(); //
// ...
}
void ApiObjDerived1::internalPolyFunc2() {
Resource& res = InternalClass::getResource1();
// ...
}
void ApiObjDerived1::apiPolyFunc1() {
// ...
}
void ApiObjDerived1::apiPolyFunc2() {
// ...
}
// ...
ApiObjDerived2.h:
#include "ApiObjBase.h"
class ApiObjDerived2 : public ApiObjBase {
protected:
int internalVariable5;
int internalVariable6;
int apiVariable5;
int apiVariable6;
public:
ApiObjDerived2() = default;
// getters, setters
void internalPolyFunc1() override;
void internalPolyFunc2() override;
void apiPolyFunc1() override;
void apiPolyFunc2() override;
}
ApiObjDerived2.cpp:
#include "ApiObjDerived2.h"
#include "InternalClass.h"
void ApiObjDerived2::internalPolyFunc1() {
Resource& res = InternalClass::getResource2();
// ...
}
void ApiObjDerived2::internalPolyFunc2() {
// ...
}
void ApiObjDerived2::apiPolyFunc1() {
// ...
}
void ApiObjDerived2::apiPolyFunc2() {
// ...
}
// ...
SomeOtherModule.cpp:
#include "ApiObjDerived2.h"
void main(int argc, char** argv) {
std::unique_ptr<ApiObjBase> apiObj = std::make_unique<ApiObjDerived2>();
apiObj.get()->apiPolyFunc1();
return EXIT_SUCCESS;
}
For this example the error would the following while linking SomeOtherModule:
(...) In function `ApiObjDerived2::internalPolyFunc1()':
(...) undefined reference to `InternalClass::getResource2()'
My only idea to this problem is to create wrapper classes (ApiObjBaseWrapper, ApiObjDerived1Wrapper, ApiObjDerived2Wrapper) for each polymorphic class and move all internal member variables and functions to them. These wrapper classes would contain the original derived class as a private member variable, which could be accessed by a virtual getter which returns a reference or a pointer to ApiObjBase. This would separate the internal and API part of the module making predeclarations unnecessary in the API, while maintaining all the advantages of polymorphism. After this, InternalClass could use ApiObjBaseWrapper, and SomeOtherModule could continue to use ApiObjBase.
My problem with this idea is that this would require a LOT of new files, classes and code (I would have to create another ~30 classes with .cpp and .h files). I cannot emphasize more how big this module is.
What do you suggest, what should I do?

which is the better approach to check in const function if something is created or not?

In my code myclass has two two const functions which are being called by some other const functions. In this class I am not modifying anything except bool variable.
In this code bool variable "isCreated" is being used to check if something is created or not. If not created then create it in function fooUpdate().
myclass.h
class myclass
{
public:
myclass()
{}
~myclass() {}
void fooUpdate() const;
void fooCreate(bool arg) const;
bool isCreated; //should I make it mutable or static
};
myclass.cpp:
void myclass::fooCreate(bool arg) const //In this function I am not modifying anything except bool variable.
{
isCreated = arg;
//create
}
void myclass::fooUpdate() const
{
if(!isCreated)
{
//create
}
else
{
//update
}
}
some other classes
//These functions will always be const. Not in my scope to change it.
create() const {
lClass.fooCreate(true);
}
update() const {
lClass.fooUpdate();
}
Now I have two options either make isCreated mutable or static. I just want to know which is better option ?
You are misusing const qualifier for member functions. Both fooUpdate and fooCreate should not be marked as const because they are supposed to modify internal state of an object. Note that "they are called by some const function" is not a valid reason to mark function as const, it actually indicates a potential logic flaw in your code.
If the calling code can not be changed then you can utilize a PImpl idiom and utilize wrapper class for legacy code:
class myclass
{
private:
bool isCreated;
public:
myclass() {}
~myclass() {}
void fooUpdate()
{
if(!isCreated)
{
isCreated = true;
//create
}
else
{
//update
}
}
void fooCreate(bool arg)
{
isCreated = arg;
}
};
class myclasswrap
{
private:
const ::std::unique_ptr<myclass> m_p_impl;
public:
myclasswrap(): m_p_impl(make_unique<myclass>()) {}
~myclasswrap() {}
// can call non-const-qualified methods of myclass just fine
void fooUpdate() const {m_p_impl->fooUpdate();}
void fooCreate(bool arg) const {m_p_impl->fooCreate();}
};
They're completely different keywords serving completely different purposes:
static means that the variable will be shared by all instances of the class. It's basically a global variable.
mutable allows fine-grained mutation of member variables even in const-qualified member functions.
They're really not comparable.

Create a temporary interface into an object?

I have an object "World obj;" that has a normal interface of methods for it's typical funcitonality, but I want to have an additional interface of methods specifically for initializing that should only be visible when I specifically need them.
An example might be like this:
class World{
public:
void draw();
void update();
void normalStuff();
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
Is there a way to relatively hide addATree(); etc in a way that makes sense? Ideally the mechanism for revealing those methods would also put the object into a ready state for them, or at least fault if it's not possible.
Different approaches would be possible:
Don't change the code, just change the spec
No need to change the code. Change the API specification and if the caller throws garbage in he gets garbage out.
Make the functions check if they are allowed
Always safe.
class World{
public:
...
void addAClown() {
if(not allowed)
throw error or crash or output error message or just return;
else {
do the work;
}
}
private:
int m_data;
};
Write a function that only exposes the Interface if allowed
You can't protect against someone getting the interface early and use it longer than allowed.
You could extract the interface functions into a separate class.
class WorldInterfaceToProtect {
public:
void addATree() = 0; // this should not be ordinarily available or visible,
void addACar() = 0; // calling this might break the object
void addAClown() = 0;// if it's not in a ready state for it
};
then the main class can protect these functions.
class World : protected WorldInterfaceToProtect {
public:
void draw();
void update();
void normalStuff();
protected:
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
You then need to add a function that exposes the interface.
class World ... {
public:
WorldInterfaceToProtect *GetInterface() { return allowed_cond ? this : nullptr; }
...
}
Separate the class itself and the builder
This only helps if the functions to be called are only allowed during construction and not later. Depending on the design of the builder you can get a good protection.
class World{
friend class WorldBuilder;
public:
void draw();
void update();
void normalStuff();
protected:
void addATree(); // this should not be ordinarily available or visible,
void addACar(); // calling this might break the object
void addAClown();// if it's not in a ready state for it
private:
int m_data;
};
class WorldBuilder {
static World *Build(...);
}
Perhaps split the world into more composable parts:
struct WorldInterface
{
virtual void draw() = 0;
virtual void update() = 0;
virtual void normalStuff() = 0;
};
class World : public WorldInterface
{
public:
void draw() override { /* actual drawing here */};
void update() override {};
void normalStuff() override {};
private:
int m_data;
};
class TreeWorld : public WorldInterface
{
public:
// takes a reference to the actual world engine and defers work to
// that
TreeWorld(World& worldEngine) : worldEngine_(worldEngine) {}
void draw() override { worldEngine_.get().draw(); };
void update() override { worldEngine_.get().update(); };
void normalStuff() override { worldEngine_.get().normalStuff(); };
void addATree() {
//do tree/world interaction here
}
private:
std::reference_wrapper<World> worldEngine_;
};
class CarWorld : public WorldInterface
{
public:
// takes a reference to the actual world engine and defers work to
// that
CarWorld(World& worldEngine) : worldEngine_(worldEngine) {}
void draw() override { worldEngine_.get().draw(); };
void update() override { worldEngine_.get().update(); };
void normalStuff() override { worldEngine_.get().normalStuff(); };
void addACar() {
//do car/world interaction here
}
private:
std::reference_wrapper<World> worldEngine_;
};
extern void play_tree_game(TreeWorld world);
extern void play_car_game(CarWorld world);
int main()
{
World worldEngine;
// initialise engine here
// play tree-phase of game
play_tree_game(TreeWorld(worldEngine));
// play car phase of game
play_car_game(CarWorld(worldEngine));
}
Good answers all around, I'll just add this because it was missing(?)
class World{
public:
void draw();
void update();
void normalStuff();
private:
int m_data;
};
class BuildableWorld : public World
{
public:
void addATree();
void addACar();
void addAClown();
};
Use the BuildableWorld at initialization phase and then just give a pointer to the base class type for others to use.
Sure, you need some way to give the "built" data for the base class to access, but that was not the issue here, right?
an alternative approach that has not been mentioned so far, may be to let addX() functions take parameters whose existence implies that World is in a valid state. Say, if you cannot add trees to a world without water, let World return an (optional) water object to pass to addTree ... in other words, you need to properly formalize World invariants:
class World{
public:
void normalStuff();
auto getAvaliableWaterBuckets() -> optional<WaterBuckets>;
auto getAvaliableSoil() -> optional<SoilPack>;
//...
void addATree( WaterBuckets&&, SoilPack&& );
//...
};
// in the meanwhile, in user land:
if( auto water = world->getAvaliableWaterBuckets() )
if( auto soil = world->getAvaliableSoil() )
world->addTree( std::move(*water), std::move(*soil) );
else
world->recycleWater( std::move(*water) );
the benefit of this approach is that the user is not forced to think about world state validity ( an error prone task ), he just thinks about what he needs in order to add a tree ( simpler, hard to use incorrectly ). Moreover, this scales well because addX() functions can share different objects ( addFlowers needs water, ... ) enabling the correct management of a possibly complex internal world state.
Of course, IMHO, if you need to use addX() strictly on world construction only ( and you don't plan to add trees later ), then the factory approach already mentioned in the comments seems the way to go ...

Static in a DLL is initialized and then not anymore

I am encountering a very strange issue in my code... I've spent now a whole afternoon and cannot get nor heads nor tails on it. But maybe someone here can point me what I'm doing wrong.
So for the explanation:
I have a DLL.
In it I have 2 classes:
class Plugin {
public:
Plugin() : isInited(false) { all_plugins.push_back(this); }
virtual ~Plugin() { }
virtual int OnInit(ONINIT_PARAMS) { return 0; }
virtual void OnDeInit(ONDEINIT_PARAMS) { }
virtual int OnTick(ONTICK_PARAMS) { return 0; }
private:
static std::vector<Plugin*> all_plugins;
private: // NO COPY CLASS
Plugin(const Plugin&);
const Plugin& operator=(const Plugin&);
};
This class is responsible for mapping the Init/DeInit/Tick function-calls which comes from the main application.
Secondly I have this:
class DynamicModule {
public:
DynamicModule() : isLoaded(false) { all_modules.push_back(this); }
virtual ~DynamicModule() { }
virtual int OnLoad() { return 0; };
virtual int OnUnload() { return 0; };
private:
static std::vector<DynamicModule*> all_modules;
private: // NO COPY CLASS
DynamicModule(const DynamicModule&);
const DynamicModule& operator=(const DynamicModule&);
};
#define IMPLEMENT_DYNAMICMODULE std::vector<DynamicModule*> DynamicModule::all_modules;
Now in plugin.cpp I do:
IMPLEMENT_DYNAMICMODULE;
std::vector<Plugin*> Plugin::all_plugins;
That takes care of the static stuff.
Now I define a class (in a header file):
class InMarket : public Plugin {
public:
int OnInit (ONINIT_PARAMS);
void OnDeInit(ONDEINIT_PARAMS);
int OnTick (ONTICK_PARAMS);
private:
};
And implement it in a C++ file:
static class InMarket _InMarket;
I traced it, and the constructor gets called correctly. And inserted into Plugin::all_plugins.
Then I continue tracing, and I see the modules (2 at the moment, defined for example like the next example [in a C++ file]):
static class MQL4Trade : public DynamicModule {
public:
virtual int OnLoad() {
__OrderSend = (_OrderSend)GetProcAddress(exe, "OrderSend");
__OrdersCount = (_OrdersCount)GetProcAddress(exe, "OrdersCount");
return 0;
}
} _MQL4Trade;
I see these modules get inserted as well nicely in DynamicModule::all_modules.
But at the same time when I see this, I also noticed the Plugin::all_plugins has a {size=0}?!
Then when I enter my OnInit() function, I see that all_modules has a size of 2, and all_plugins = 0. Even though ALL of the constructors had been called?
I load my library as:
HMODULE plugin = LoadLibrary(pluginFilename.c_str());
All static objects constructors are called....
And I don't see ANY differences between the 2 things.
What is going on here?

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