If the data belongs to a derived class, let the derived class do what it wants to contain.
By placing this data in a base class (non-confidential), you force each derived class to have it. Derived classes should not be forced to do anything unless they need to populate a data element, for example. The base class defines what derived classes should do, not how they should do it.
If you find that there might be a common theme, you can create a derived class that has those elements and implementations that should then be the base class for those who want to use it. For example:
struct car
{
virtual ~car(){}
virtual unsigned year(void) const = 0;
virtual const std::string make(void) const = 0;
}
struct dodge_car
{
virtual ~car(){}
virtual unsigned year(void) const = 0;
const std::string make(void) const
{
static const std::string result = "Dodge";
return result;
}
}
Etc. But you see that any derived classes still have a choice for implementing the entire car interface. It also improves code cleanliness. By supporting the real interface, implementation details will not interfere.
, , , , , , , .