Reputation: 1239
I have a base class and derived classes. The base class uses pure virtual methods to require the derived classes to implement methods - otherwise it doesn't compile. Classic.
Can I also require from the base class that the derived classes give a value for a constant ? It has to be a compile-time constant, but also it has to be a compilation error if they don't give a value for the constant. It is also static to each derived class since it is instance-independent.
I have seen answers suggesting to write a pure virtual getter which returns a value, but the getter could then have dynamic code with changing behavior depending on some conditions. I really mean this to be a lifelong constant. Also, since it's not static in that solution, there might be one instance of that constant value for each instance of the derived classes, and that's a waste of memory.
Basically like a name or id. Here is what it would sort of look like, but of course that doesn't compile for multiple reasons.
class Base
{
Base();
~Base();
virtual void doSomething() = 0;
/* Unknown for Base, meant as an abstract / pure virtual class,
but required for all derived classes. */
static const int id;
}
class VariantA : public Base
{
VariantA();
~VariantA();
static const int id = 215684;
void doSomething() {...}
SomeType someData;
};
class VariantB : public Base
{
VariantB();
~VariantB();
static const int id = 6451322;
void doSomething() {... /* do it differently than VariantA */}
SomeOtherType someOtherData;
};
id
never changes and does not depend on the instance, but does depend on which derived class we are handling at any given moment. Simply having an object of a class that inherits from Base
guarantees that we have such a thing as id
, however the value varies, not depending on the object as an instance, but simply on the class of the object.
Upvotes: -2
Views: 154
Reputation: 14673
Within these constraints you cannot do better than a virtual getter (which means run-time):
struct Base {
enum { idN = 0 };
virtual int id() { return idN; }
};
struct Derived : Base {
enum { idN = Base::idN + 1 };
int id() override { return idN; } // note: it's actually Derived::idN
};
If that is meant for use only inside of a base class implementation,the very idea is a sign of flawed design - something is becoming a "god class" there. You rather should do behaviour injection. As your concern is used memory I sugges to look at Flyweight pattern, perhaps it's what you actually need instead of managing individual "small objects".
Upvotes: 1