Search code examples
c++virtualdestructor

Why std::unary_function doesn't contain virtual destructor


I came across class template std::unary_function and std::binary_function.

template <class Arg, class Result>
struct unary_function {
    typedef Arg argument_type;
    typedef Result result_type;
};

template <class Arg1, class Arg2, class Result>
struct binary_function {
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
};

Both these can be used as base class for specific purposes. But still there's no virtual destructor in these. One reason which I could guess is these are not meant to be treated polymorphically. i.e

std::unary_function* ptr; 
//intialize it 
//do something
delete ptr;

But if that is so, shouldn't destructor be there with protected access specifier so that compiler would break any attempt to do that.


Solution

  • In a well-balanced C++ design philosophy the idea of "preventing" something from happening is mostly applicable when there's a good chance of accidental and not-easily-detectable misuse. And even in that case the preventive measures are only applicable when they don't impose any significant penalties. The purpose of such classes as unary_function, binary_function, iterator etc. should be sufficiently clear to anyone who knows about them. It would take a completely clueless user to use them incorrectly.

    In case of classes that implement the well-established idiom of "group member injection" through public inheritance, adding a virtual destructor to the would be a major design error. Turning a non-polymorphic class into a polymorphic one is a major qualitative change. Paying such price for the ability to use this idiom would be prohibitively unacceptable.

    A non-virtual protected destructor is a different story... I don't know why they didn't go that way. Maybe it just looked unnecessarily excessive to add a member function to that purpose alone (since otherwise, these classes contain only typedefs).

    Note that even though unary_function, binary_function are deprecated, iterator is not. The deprecation does not target the idiom itself. The idiom is widely used within other larger-scale design approaches, like C++ implementation of Mixins and such.