Reputation: 1327
I have a Controller
class which is designed to be inherited. It currently has a name()
pure virtual method, like this:
class Controller {
public:
virtual const std::string name() const = 0;
}
The name is really a class-property, rather than an instance property. It shouldn't change between instances of a subclass, so really, virtual isn't the best thing to do here. Anyway, I've now hit a problem where I need the name at compile-time, in a template function. Obviously T::name()
doesn't work, and because the subclasses won't be default constructible, I can't even hack around it with T()::name()
.
So something needs to change, but I can't figure out the best way to do this. I need to be able to access name in the following situations:
T::name()
)instance->name()
)Controller*
(e.g. pointer to the base class)name()
doesn't have to be method, it can be a public attribute, or something else. But no-matter what I try I can only seem to satisfy 2 of the above 3 requirements.
Can anyone suggest any good approaches for solving this?
Upvotes: 0
Views: 244
Reputation: 176
Unfortunately, you cannot declare a static method virtual so something like this wouldn't work :
struct BaseClass {
static virtual std::string name() =0;
};
struct ChildClass {
static std::string name() {
return "my_name";
}
};
you can instead make a method with a slightly different name :
struct BaseClass {
virtual std::string name() =0;
};
struct ChildClass {
std::string name() {
return ChildClass::_name();
};
static std::string _name() {
return "my_name";
}
};
which will work with the three cases you describe :
ChildClass c;
BaseClass& b = c;
std::cout << ChildClass::_name() << std::endl;
std::cout << c.name() << std::endl;
std::cout << b.name() << std::endl;
Upvotes: 1