I have a private static member variable of a class Central, with type map. I want to populate this map with ” Base* ” pointers, which point to instances of classes deriving from ” Base “. These instances of the derived classes must be stored in dynamic memory. There is a bit of template fun involved also. I did try a method to populate the map, but it gave me a compilation error (which will be stated later).
Here is a code snippet for clarity:
#include <all_necesary_std_headers>
class Base
{
/* guts */
};
template<class CType>
class Derived: public Base
{
/* innards */
};
class Central
{
/* partial entrails */
private:
// the static map I was referring to
static std::map<string, Base*> base_map;
};
// Initializing the static map here
std::map<string, Base*> Central::base_map;
class Test1
{
/* viscera */
};
// Compilation error here, on next line of code.
Central::base_map["Test1"] = dynamic_cast<Base*>( new Derived<Test1>);
class Test2
{
/* bowels */
};
// Compilation error here, on next line of code.
Central::base_map["Test2"] = dynamic_cast<Base*>( new Derived<Test2>);
This is the Compilation error that I get:
error: expected constructor, destructor, or type conversion before ‘=’ token;
I already have a destructor that frees the memory allocated by the map, so no need to remind me. I want to use the class ” Central ” in main(). This class structure will be used to dynamically create new instances of classes, from class names stored in files.
Hope it is clear, please say if anything isn’t.
Assignment statements can only go in functions, not at namespace scope.
In C++11, you can initialise the map in its declaration:
If you’re stuck in the past, then you’ll need to use a function to populate the map; perhaps something like:
Also, note that you can’t use
dynamic_castunless these types are polymorphic (i.e.Basehas at least one virtual function). You can convertDerived<T>*toBase*without a cast, as I’ve done in my examples; but if you need to convert back withdynamic_castthen you’ll need to make sure they are polymorphic.UPDATE: If you want to be able to register each class separately by adding code only to that class’s implementation files, then you’ll need to declare a static object that registers the class in its constructor. Now we run into the initialisation order fiasco: if static objects are initialised in different translation units then the initialisation order is unspecified, so you can’t safely access one from the constructor of the other.
We can fix this by making the map a local static variable, initialised the first time it’s accessed:
Now we can define the class to register the classes:
And use it for each class:
(Alternatively, you could make it a static namespace-scope object in the source file, rather than a static member; the choice is largely aesthetic. Unfortunately, whatever you do will have to be defined in the source file due to the One Definition Rule.)