c++ - 为什么 C++ STL 如此大量地基于模板? (而不是在*接口(interface)*上)

标签 c++ oop templates stl

我的意思是,除了它的强制性名称(标准模板库)...

C++ 最初打算将 OOP 概念呈现到 C 中。也就是说:您可以根据其类和类层次结构来判断特定实体可以做什么和不能做什么(无论它如何做)。由于多重继承的问题,以及 C++ 以某种笨拙的方式支持接口(interface)概念的事实(与 java 等相比),一些能力的组合更难以用这种方式描述,但它就在那里(并且可能是改进)。

然后模板和 STL 一起发挥了作用。 STL 似乎采用了经典的 OOP 概念并将它们冲入下水道,而是使用模板。

当使用模板来泛化类型本身与模板(例如容器)的操作无关的类型时,应该区分情况。有一个 vector<int>完全有道理。

然而,在许多其他情况下(迭代器和算法),模板化类型应该遵循一个“概念”(输入迭代器、前向迭代器等),其中概念的实际细节完全由模板的实现来定义函数/类,而不是与模板一起使用的类型的类,这在某种程度上是 OOP 的反用法。

例如,您可以告诉函数:

void MyFunc(ForwardIterator<...> *I);

更新:由于原始问题中不清楚, ForwardIterator 可以被模板化以允许任何 ForwardIterator 类型。相反,将 ForwardIterator 作为一个概念。

仅通过查看其定义来期望前向迭代器,您需要查看其实现或文档:
template <typename Type> void MyFunc(Type *I);

我可以提出两个支持使用模板的声明:通过为每个使用的类型定制编译模板,而不是使用 vtables,可以使编译后的代码更高效。以及模板可以与 native 类型一起使用的事实。

但是,我正在寻找一个更深刻的原因,为什么放弃经典的 OOP 而支持 STL 的模板? (假设你读了那么远:P)

最佳答案

简短的回答是“因为 C++ 已经向前发展了”。是的,早在 70 年代后期,Stroustrup 就打算创建具有 OOP 功能的升级版 C,但那是很久以前的事了。到 1998 年该语言标准化时,它已不再是 OOP 语言。它是一种多范式语言。它当然对 OOP 代码有一些支持,但它也覆盖了图灵完备的模板语言,它允许编译时元编程,人们发现了泛型编程。突然之间,OOP 似乎不再那么重要了。当我们可以通过使用模板和泛型编程提供的技术编写更简单、更简洁和更高效的代码时,情况并非如此。

OOP 不是 chalice 。这是一个可爱的想法,它比 20 世纪 70 年代发明的过程语言有了很大的改进。但老实说,这并不是它被破解的全部。在许多情况下,它笨拙而冗长,并没有真正促进可重用代码或模块化。

这就是今天 C++ 社区对泛型编程更感兴趣的原因,也是为什么每个人终于开始意识到函数式编程也非常聪明的原因。 OOP 本身并不是一个美丽的景象。

尝试绘制一个假设的“OOP 化”STL 的依赖图。有多少类(class)必须相互了解?会有很多依赖。你能不能只包括 vector标题,也没有得到 iterator甚至 iostream拉进来了? STL 使这变得容易。 vector 知道它定义的迭代器类型,仅此而已。 STL 算法一无所知。它们甚至不需要包含迭代器头,即使它们都接受迭代器作为参数。哪个更模块化?

STL 可能不遵循Java 定义的OOP 规则,但它是否达到了OOP 的目标?不是实现了复用性、低耦合性、模块化和封装性吗?

它不是比 OOP 化版本更好地实现这些目标吗?

至于为什么 STL 被采用到语言中,发生了几件事导致了 STL。

首先,模板被添加到 C++ 中。添加它们的原因与将泛型添加到 .NET 的原因大致相同。能够在不丢弃类型安全的情况下编写诸如“T 类型的容器”之类的东西似乎是一个好主意。当然,他们确定的实现要复杂得多,而且功能强大得多。

然后人们发现他们添加的模板机制比预期的更强大。有人开始尝试使用模板来编写更通用的库。一种受函数式编程启发,另一种使用 C++ 的所有新功能。

他将它提交给了 C++ 语言委员会,后者花了很长时间才适应它,因为它看起来如此奇怪和不同,但最终意识到它比他们必须以其他方式包含的传统 OOP 等价物更有效。所以他们对其进行了一些调整,并将其纳入标准库。

这不是意识形态的选择,也不是“我们要不要OOP”的政治选择,而是一个非常务实的选择。他们评估了这个库,发现它运行良好。

无论如何,您提到的支持 STL 的两个原因都是绝对必要的。

C++ 标准库 高效。如果它比等效的手动 C 代码效率低,那么人们就不会使用它。这会降低生产力,增加出现错误的可能性,而且总体来说只是一个坏主意。

和 STL 使用原始类型,因为原始类型是 C 语言中的全部,而且它们是两种语言的主要部分。如果 STL 不适用于 native 数组,则为 没用 .

您的问题有一个强有力的假设,即 OOP 是“最好的”。我很想知道为什么。你问他们为什么“放弃经典的 OOP”。我想知道为什么他们应该坚持下去。它有哪些优势?

关于c++ - 为什么 C++ STL 如此大量地基于模板? (而不是在*接口(interface)*上),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1039853/

相关文章:

c++ - 如何编写构造函数

java - 显示异构项目列表时采用什么设计方法

PHP/JS 表单类 - 数组与 OO

c++ - 在 C++ 中使用模板化方法交替传递仿函数和函数指针

c++ - 使用一个函数对两个不同的 vector (每个 vector 都有 "active"bool)进行排序

c++ - 什么是 typedef cell (*proc_type)(const std::vector<cell> &);做?

c++ - 全局重新定义多个冲突的预处理器定义

C++/CX 工厂类提供具有相同数量参数的重载构造函数

php - C++ HexToBin VS PHP Hex2Bin 函数。输出不同

c++ - 从类型而不是变量获取指针级别