为什么std :: unary_function不包含虚析构函数

时间:2014-12-23 17:42:06

标签: c++ virtual destructor

我遇到了课程模板std::unary_functionstd::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访问说明符来构造析构函数,以便编译器可以破坏任何尝试。

3 个答案:

答案 0 :(得分:7)

在一个均衡的C ++设计理念中,&#34;预防&#34;发生的事情大多适用于意外和不易察觉的误用的可能性。即使在这种情况下,预防措施仅适用于未施加任何重大处罚的情况。 unary_functionbinary_functioniterator等类的目的应该对任何了解它们的人都足够清楚。一个完全无能的用户将错误地使用它们。

如果课程实现了成熟的成语注释&#34;组成员注射&#34;通过公共继承,添加虚拟析构函数将是一个主要的设计错误。将非多态类转换为多态类是一个重大的质变。为这种习语的使用付出这样的代价是非常不可接受的。

非虚拟保护的析构函数是一个不同的故事...我不知道为什么他们没有这样做。也许只是看起来不必要地过多地将成员函数添加到该目的(因为否则,这些类仅包含typedef s。)

请注意,即使unary_functionbinary_function已弃用,iterator也不推荐使用。弃用不针对习语本身。这个成语广泛用于其他大型设计方法,如 Mixins 的C ++实现等。

答案 1 :(得分:3)

因为std::unary_functionstd::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; (假设它们被认为是破碎的)。