我遇到了课程模板std::unary_function
和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;
};
这两者都可以用作特定目的的基类。但仍然没有虚拟析构函数。我可以猜到的一个原因是这些并不意味着要进行多态处理。即
std::unary_function* ptr;
//intialize it
//do something
delete ptr;
但如果是这样的话,不应该使用protected
访问说明符来构造析构函数,以便编译器可以破坏任何尝试。
答案 0 :(得分:7)
在一个均衡的C ++设计理念中,&#34;预防&#34;发生的事情大多适用于意外和不易察觉的误用的可能性。即使在这种情况下,预防措施仅适用于未施加任何重大处罚的情况。 unary_function
,binary_function
,iterator
等类的目的应该对任何了解它们的人都足够清楚。一个完全无能的用户将错误地使用它们。
如果课程实现了成熟的成语注释&#34;组成员注射&#34;通过公共继承,添加虚拟析构函数将是一个主要的设计错误。将非多态类转换为多态类是一个重大的质变。为这种习语的使用付出这样的代价是非常不可接受的。
非虚拟保护的析构函数是一个不同的故事...我不知道为什么他们没有这样做。也许只是看起来不必要地过多地将成员函数添加到该目的(因为否则,这些类仅包含typedef
s。)
请注意,即使unary_function
,binary_function
已弃用,iterator
也不推荐使用。弃用不针对习语本身。这个成语广泛用于其他大型设计方法,如 Mixins 的C ++实现等。
答案 1 :(得分:3)
因为std::unary_function
和std::binary_function
在设计上不应该用于多态删除:它们只是为子类提供typedef而没有其他意图。
作为C ++中的基类并不意味着该类必须表现出任何特定的多态行为。
即。你永远不应该看到如下代码:
void foo(std::unary_function* f)
{
delete f; // illegal
}
请注意,自C ++ 11(See N3145)
以来,这两个类都已弃用答案 2 :(得分:2)
各种类型标签的基本原因(例如,还有std::iterator<...>
)与那些相信所有衍生出来的人很好地发挥作用是一个基类是STL的整体设计他们在哪里使用继承进行多态时使用皱眉。也就是说,提出这些类的人不会看到为什么任何人想要动态多态的任何理由,特别是没有任何这些空的设计类型标签。因此,很少努力防止愚蠢的错误。
当这些类被广泛接受为STL的一部分时,在删除STL的粗糙边缘上花费了更多的精力,而不是在不重要的细节上。此外,将类型标记设置为空可能很有用,因为它们不会干扰使用任何访问说明符的类上的某些约束。因此,类型标签留空。
因为特别不需要在C ++ 11中使用任何这些类型的特性(返回类型可以在使用时确定并且参数可以完美转发)这些类型被弃用而不是获得&#34;固定&#34; (假设它们被认为是破碎的)。