Here's one way.
Add a pure virtual method to IScheduler
:
virtual const char *getId() const =0;
Then put every subclass to it's own .h or .cpp file, and define the function:
virtual const char *getId() const { return __FILE__; }
Additionally, for use from templates where you do have the exact type at compile time, in the same file define static method you can use without having class instance (AKA static polymorphism):
static const char *staticId() { return __FILE__; }
Then use this as cache map key. __FILE__
is in the C++ standard, so this is portable too.
Important note: use proper string compare instead of just comparing pointers. Perhaps return std::string
instead of char*
to avoid accidents. On the plus side, you can then compare with any string values, save them to file etc, you don't have to use only values returned by these methods.
If you want to compare pointers (like for efficiency), you need a bit more code to ensure you have exactly one pointer value per class (add private static member variable declaration in .h and definition+initialization with FILE in corresponding .cpp, and then return that), and only use the values returned by these methods.
Note about class hierarchy, if you have something like
A
inherits IScheduler
, must override getId()
A2
inherits A
, compiler does not complain about forgetting getId()
Then if you want to make sure you don't accidentally forget to override getId()
, you should instead have
- abstract
Abase
inherits IScheduler
, without defining getId()
- final
A
inherits Abase
, and must add getId()
- final
A2
inherits Abase
, and must add getId()
, in addition to changes to A
(Note: final
keyword identifier with special meaning is C++11 feature, for earlier versions just leave it out...)