C++ STL背后的设计原理

C++ STL背后的设计原理,c++,stl,C++,Stl,我查看了一些STL实现的源代码(SGI、STLport、libc++),看到了一些似乎在所有或大多数实现中都很常见的设计模式,但我找不到这样做的理由。我想一定有一个很好的原因,我想知道它是什么: 许多类,包括vector和list\u iterator等,被实现为两个类,例如带有部分功能的list\u iterator\u base,然后是继承接口其余部分的list\u iterator\u base。重点是什么?似乎在一节课上就可以轻松完成 迭代器似乎没有使用迭代器类。使用它是否会造成性能损失

我查看了一些STL实现的源代码(SGI、STLport、libc++),看到了一些似乎在所有或大多数实现中都很常见的设计模式,但我找不到这样做的理由。我想一定有一个很好的原因,我想知道它是什么:

  • 许多类,包括
    vector
    list\u iterator
    等,被实现为两个类,例如带有部分功能的
    list\u iterator\u base
    ,然后是继承接口其余部分的
    list\u iterator\u base
    。重点是什么?似乎在一节课上就可以轻松完成

  • 迭代器似乎没有使用
    迭代器
    类。使用它是否会造成性能损失


  • 这是我在快速浏览中发现的两个问题。如果有人知道一个很好的资源来解释STL实现的基本原理,我会很高兴听到它。

    答案相当直截了当:

  • STL是关于泛型编程的。关键的想法是不要有重复的代码。当前的目标是不复制源代码,但事实证明,不复制二进制代码也是有意义的。因此,STL组件将常用零件剔除并使用它们是很常见的。列表类的链接或向量的类型无关属性只是两个示例。对于向量,甚至有多个层:一些部分完全独立于类型(例如大小),其他部分只需要类型本身(例如,所有访问器、迭代器等),一些部分需要知道如何处理资源分配(例如,插入和销毁需要知道正在使用的分配器)
  • 事实证明,
    std::iterator
    并没有真正起作用:在基类中定义的类型依赖于模板参数,在从这样一个基类派生的类模板中无法直接访问。也就是说,类型需要用基类限定,并且需要使用
    typename
    标记为类型。更糟糕的是,理论上,用户可以分配派生类的对象,并通过指向
    std::iterator
    的指针释放它们(是的,这样做很愚蠢)。也就是说,没有好处,只有潜在的缺点,即最好避免

  • 也就是说,我不知道有什么好的资源涵盖实现泛型库的技术。STL实现中应用的大多数细节都是由多人独立发明的,但关于泛型编程的文献仍然相对较少。我不认为任何描述STL的论文实际上讨论了实现技术:它们通常集中在设计细节上。鉴于似乎只有很少的人理解STL是关于什么的,因此作者倾向于专注于描述什么是STL而不是如何实现STL也就不足为奇了。

    请注意,从技术上讲,STL和标准库(stdlib)是不同的。后者在很大程度上源于前者,当时它被添加到官方语言标准中。几乎没有人再使用“真正的”STL,而是使用标准库的实现(例如libc++)。不管怎样,很多人都把stdlib称为STL,这通常是好的,但对于你的问题来说,这种区别改变了它的含义。@DaveNewton我不理解你的评论。可能是原始发明家(Stepanov、Lee和Musser)的出版物、采访、演示和书籍STL的所有部分都是一个可以查看的地方for@Zane:问题不在于接口的设计,而在于接口的实现。界面的设计很容易在Stepanov的文章和访谈中找到,但实现的“血淋淋”细节并非如此(即,为什么要将迭代器分为两种类型,即
    x_迭代器基
    和实际的
    x_迭代器
    。这是一种矛盾修饰法,类似于“设计原理”这是一个C++笑话。关于第2点:如果它不工作,为什么要保持它?为什么它被添加到标准库?