Are there any circumstances in which it is legitimate for a derived
class to have a non-virtual destructor?
Yes.
A non-virtual destructor signifies that a class should not be used as
a base-class.
Not really; a non-virtual destructor signifies that deleting an instance of derived
via a base
pointer will not work. For example:
class Base {};
class Derived : public Base {};
Base* b = new Derived;
delete b; // Does not call Derived's destructor!
If you don't do delete
in the above manner, then it will be fine. But if that's the case, then you would probably be using composition and not inheritance.
Will having a non-virtual destructor of a derived class act like a
weak form of the Java final modifier?
No, because virtual
-ness propagates to derived classes.
class Base
{
public:
virtual ~Base() {}
virtual void Foo() {};
};
class Derived : public Base
{
public:
~Derived() {} // Will also be virtual
void Foo() {}; // Will also be virtual
};
There isn't a built-in language mechanism in C++03 or earlier to prevent subclasses(*). Which isn't much of an issue anyway since you should always prefer composition over inheritance. That is, use inheritance when a "is-a" relationship makes more sense than a true "has-a" relationship.
(*) 'final' modifier was introduced in C++11