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.
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 typedef
s).
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.
Because std::unary_function
and std::binary_function
are, by design, not supposed to be used for polymorphic deletion : they exist only to provide typedefs to the child classes, and have no other intent.
Being a base class in C++ does not mean that the class must exhibit any particular polymorphic behaviour.
i.e. you should never see code such as :
void foo(std::unary_function* f)
{
delete f; // illegal
}
Note that both classes are deprecated since C++11 (See N3145)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With