I’ve always heard that you shouldn’t inherit from a class without virtual destructors, and I didn’t pay much attention because I just don’t use inheritance all that often. Does this rule apply even if you don’t want to use polymorphism, but you just want all of a class functionality, and you want to add some more? To be concrete, would the following class be safe, with well defined behavior, as long as I didn’t use it polymorphically? (i.e. no deleting base pointers to derived objects)
template<typename T>
class SomewhatSafeVector : public std::vector<T>
{
public:
typedef std::vector<T> base;
T& operator[](unsigned n) {
if (n >= base::size())
{
throw IndexOutOfBounds();
}
return base::operator[](n);
}
};
This is a rule of thumb given to beginners because explaining all the intricacies take too much time and it is just safer (and not that much costly for exercices programs) to actually give them just a few base lines that work all the times (though may be overkill).
You can perfectly use inheritance without a
virtualdestructor in the base class. On the other hand, if the base class has novirtualmethod at all, then inheritance is probably the wrong tool for the job. For example: in your case if I useSafeVector<T> sv; sv[3];then it is safe, however if I dostd::vector<T>& v = sv; v[3];it is not… this is because you are merely hiding the base class method, not overriding it (crank up your warning level, they’ll let you know).The proper way here would be to use composition, and then create forwarding methods to the implementation member for those methods you really use. In practice, it gets tiring because C++ does not support delegation (
using attribute.insert;) so many resort to inheriting…Another alternative is to provide the safer methods as free methods, since you can always add free methods without restriction. It might feel less idiomatic to people with the “OO” mindset, and some operators cannot be so added.