C ++:STL和Boost的替代方案?

时间:2011-04-27 04:59:01

标签: c++ boost stl

C ++ 多范式语言, STL Boost 是针对功能构建的该语言的范例。 STL由容器(用于保存数据),迭代器(用于访问数据)和算法(用于操作数据的函数)组成。通过使用迭代器将算法函数应用于容器。作为副作用,这些方法不是容器类的一部分,而是完全独立的。 (这避免了库编写者的冗余,但对于库用户来说却很痛苦。)

是否有STL / Boost的C ++替代品以更传统的面向对象的方式提供这样的容器?我正在寻找字符串,向量,链表,地图,树,哈希表等。容器应该易于继承和扩展。相比之下,从STL / Boost扩展类是very bad idea,这是他们设计师的设计。

PS:请不要使用下面的回复空间来证明STL / Boost的优势。我很清楚他们! : - )

8 个答案:

答案 0 :(得分:31)

许多(大多数!)旧的C ++库使用的容器与Java和C#中使用的容器更为相似。

此类库的一些示例包括COOLET++NIH Class LibraryRogue Wave Tools.h++

两点:

  1. 最多,这些都是灵感来源。我很确定它已经至少10年(通常更像是20年),因为它们中的任何一个都已更新。他们中的任何一个都无法用任何合理的当前编译器进行编译。
  2. 我想记录在案,指出我只是在回答一个非常具体的问题时提供这些链接。我肯定会建议您使用上述任何代码,我也不建议您甚至将它们用作灵感。
  3. 为了确保我在这里很清楚,至少是IMO:

    • 你问题中的指控是完全错误的。
    • 你要做的事情完全是疯了!
    • 你在浪费时间。
    • 以这种方式编写代码是一个非常非常糟糕的主意。只说不!
    • 如果你坚持这样做,你将成为一个贱民。
      1. 即使是那些不太了解原因的非程序员,也会开始非常讨厌你。
      2. 你的狗会用你的鞋子和床作为他的厕所。

    你是独立的。你被警告了!

    幽默受损的隐藏字幕:当然其中一些是幽默的 - 虽然 是一个非常非常糟糕的想法

答案 1 :(得分:25)

  

这可以避免库的冗余   作家,但对图书馆来说是痛苦的   用户。

我完全不同意这个前提。即使我这样做,也是一个巨大的过度概括,并不适用于每个图书馆用户。但无论如何这是一个主观陈述,所以我会忽略它。


  

是否有C ++替代品   提供此类容器的STL / Boost   在更传统的面向对象中   味?

     

...

     

容器应该有方法   允许一个人操纵他们   直。 (例如,打电话   vector.sort()而不是   排序(vector.begin(),vector.end())。

不确定。只需创建自己的容器,将标准容器作为数据成员,并根据需要通过成员函数委托对它们和算法的调用。实施起来相当简单:

template<typename T>
class MyVector
{
public:
    void sort()
    {
        std::sort(vec.begin(), vec.end());
    }

    // ...
private:
    std::vector<T> vec;
};

C ++中没有什么可以阻止你做这样的事情,具有讽刺意味的是,由于C ++的多范式性质,你似乎不同意。

如果您不想写出包装函数,则可以使用private继承和using声明。


  

STL / Boost让你感到痛苦   从他们的容器中伸出来。

那是因为你不应该从他们那里得到。正确的方法是使用合成,就像我上面提到的代码片段一样。

答案 2 :(得分:7)

STL和Boost就像你可以得到的那样面向对象。

  1. 出于所有理论目的,成员函数和第一个参数上重载的自由函数是相同的。它们在实践中的行为非常相似,包括继承,因此在C ++中,你应该考虑将(可能是const)引用作为第一个参数的自由函数作为第一个参数的方法。

    自由函数的优点是可以为现有类定义它们,允许您向现有类添加接口。这就是为什么STL,特别是强化使用它们的原因。成员函数的主要优点是它们可以是虚拟的(但虚拟方法应该是私有的!)

  2. 您不希望通过派生来扩展集合。通常,您不希望通过派生来扩展任何内容,除非它是专门为其设计的抽象基类。请参阅this question about advantages of composition over inheritance

答案 3 :(得分:6)

你走错了路。如果你想用Java编程,那么用Java编程。如果你用C ++编程,那么就像C ++程序员那样编程。永远和当前一起游泳,永远不要反对它。

答案 4 :(得分:3)

看看Qt4的方法,我一直都是它的粉丝。

更新了链接。

答案 5 :(得分:1)

对这个派对来说有点晚了我知道OP特别要求他们不要“教诲”,因为他们已经知道了STL,但是......

与Alex Stepanov有一个古老的Dr. Dobbs interview,他是通用编程的先驱,也是STL的主要贡献者。这有几个方面非常有启发性,特别是为了解决为什么在STL中不使用更多标准OO技术的问题。一段突出:

  

即使是现在,C ++继承对泛型编程也没有多大用处。我们来讨论一下原因。许多人试图使用继承来实现数据结构和容器类。正如我们现在所知,成功的尝试几乎没有。 C ++继承以及与之相关的编程风格受到极大限制。实现一种包含平等使用它的设计是不可能的。如果从层次结构的根开始使用基类X,并在此类上定义一个虚拟相等运算符,该运算符采用类型X的参数,则从类X派生类Y.相等的接口是什么?它具有将Y与X进行比较的平等。以动物为例(OO人爱动物),定义哺乳动物并从哺乳动物中获取长颈鹿。然后定义成员函数配偶,其中动物与动物交配并返回动物。然后你从动物中获取长颈鹿,当然,它有一个功能伴侣,长颈鹿与动物交配并返回动物。这绝对不是你想要的。虽然交配对C ++程序员来说可能不是很重要,但是平等是。我不知道没有使用某种等式的单一算法。

对于那些喜欢Java解答同样难题的人,Josh Bloch努力在Effective Java中提出相同的观点,第8项:在覆盖时服从一般联系。

这是一个很好的章节,有一个很好的例子,试图保留equals契约,同时扩展一个简单的Point类并添加颜色:ColorPoint类。他继续证明OOP存在一个基本限制:无法扩展可实例化类并在保留等于合同的同时添加值组件

当然,布洛赫声明更简洁,但他们(正确地)得出了相同的结论。主要区别在于Java是一种“纯粹的OO”语言 - 所有东西都必须存在于一个类中,甚至是算法之类的东西,它们不是天生的对象。

我认为Bloch可能对这个问题很敏感,因为他在Java库中看到它失败了:继承自Vector的堆栈是Java中一个值得注意的设计问题的一个例子。

稍后在采访中,斯捷潘诺夫接着说:

  

我早期参加了贝尔实验室关于设计模板的几个讨论,并与Bjarne争论说他应该使C ++模板尽可能接近Ada仿制药。我认为我如此激烈地争辩说他决定反对。有些人认为,我意识到在C ++中使用模板函数的重要性,而不仅仅是模板类。但是,我认为模板函数应该像Ada泛型一样工作,也就是说,它们应该被显式实例化。 Bjarne不听我的意见,他设计了一个模板函数机制,其中模板使用重载机制隐式实例化。这项特殊技术对我的工作至关重要,因为我发现它允许我做很多在Ada中无法实现的事情。我认为Bjarne的这个特殊设计是一项了不起的工作,我很高兴他没有听从我的建议。

答案 6 :(得分:0)

为什么不使用图形而不是STL容器并在节点或边上附加所需的内容。他们可以模仿任何STL容器(我错了吗?)。您可以轻松地遍历节点或边缘(DFS,BFS),以及您可以对节点和边上附加的数据执行的操作。算法和迭代器的简单组合,不是吗?

答案 7 :(得分:0)

Dilawar所说的实际上是满足您所有容器需求的解决方案。

使用Boost :: graph或类似的实现。您可以将它[我就是这样]用作对象管理系统。

至于对STL的批评,这只是一个品味而非技术异议的问题。这些存在,但不是在这个层面。