我应该重新实现大多数C ++的好主意/坏主意吗?

时间:2009-03-12 10:14:34

标签: c++ code-reuse standard-library

最近,在阅读this博文后,我的脑子里有了一个危险的想法。这个想法可以这样表达:

我不需要C ++标准库提供的大部分内容。那么,为什么我不实现一个不太通用但更易于使用的版本?

作为一个例子,使用STL吐出大量难以理解和损坏的编译器错误。但是,我不关心分配器,迭代器等。那么为什么我不花几个小时来实现一个易于使用的链表类,例如?

我想从StackOverflow社区了解到:对于C ++中的大多数现有功能而言,“滚动我自己”有哪些危险,可能的缺点和可能的优势?

编辑:我觉得人们对这个想法误解了我。我的想法是要了解我是否可以实现一个非常简化的非常小的STL功能集 - 更像是一个教我数据结构等的项目。我不建议从头开始重新发明整个车轮,只是我需要和想要了解的部分。 我想我想弄清楚的是,使用STL的复杂性是否需要创建更小,更简单的版本。

重新使用提升或类似。

我编码的大部分内容都是针对大学的,我们不允许使用外部库。所以它可以是C ++标准库,也可以是我自己的类。

这个问题的客观性。

这个问题主观。也不应该是社区维基,因为它不是民意调查。我想要具体的论点,突出一个优势或一个缺点,可能可能与我的方法发生。与流行的看法相反,这不是意见,而是基于经验或良好的逻辑论证。

格式。

每个答案只能发布一个优势一个优势。这将允许人们一次评估个人想法而不是所有想法。

请...

没有宗教战争。我不是任何语言的粉丝。我用任何适用的东西。对于图形和数据压缩(我目前正在研究的),似乎是C ++。请限制您对问题的回答,否则他们将被低估。

20 个答案:

答案 0 :(得分:76)

答案 1 :(得分:43)

缺点:没有人,但你会使用它。

优势:在实施过程中,您将了解为什么标准库是一件好事。

答案 2 :(得分:22)

优点:吃自己的狗食。你完全得到你所做的。

缺点:吃自己的狗食。许多人,比我们99%的人聪明,多年来一直在创造STL。

答案 3 :(得分:13)

我建议你了解原因:

  

使用STL吐出大量的   难以理解和破坏的编译器   错误

第一

答案 4 :(得分:8)

缺点:您可能花费更多时间来调试您的课程库,而不是解决您面前的任何大学任务。

优势:你可能会学到很多东西!

答案 5 :(得分:8)

您可以对隐藏的编译器STL错误消息执行某些操作。 STLFilt将有助于简化它们。来自STLFilt Website

  

STLFilt简化和/或重新格式化   冗长的C ++错误和警告   消息,重点是与STL相关   诊断(对于MSVC 6,它完全是   消除了C4786警告及其警告   碎屑)。结果呈现出许多   即使是最神秘的诊断   理解的。

看看here,如果您使用的是VisualC,还要here

答案 6 :(得分:8)

我认为你应该这样做。

我确信我会为此感到高兴,但是你知道,这里的每个C ++程序员都喝了太多的STL coolaid。

STL是一个很棒的图书馆,但我从第一手经验中知道,如果你自己动手,你可以:

1)使其比特定用例的STL更快。 2)你将只用你需要的接口编写一个库。 3)你将能够扩展所有标准的东西。 (我不能告诉你我多么希望std :: string有一个split()方法)...

当他们说这将是一项很多工作时,每个人都是对的。那是真的。

但是,你会学到很多东西。即使你在写完之后再回到STL并且再也不用它,你仍然会学到很多东西。

答案 7 :(得分:4)

缺点:恕我直言,重新启用经过测试和验证的库是一个rabit漏洞,几乎可以保证它比它的价值更麻烦。

答案 8 :(得分:4)

我的一点经验:不久前我已经实现了我自己的类矢量类,因为我需要对它进行良好的控制。

由于我需要通用性,我制作了模板化数组。

我也想迭代它不使用operator []但是增加一个像C一样的指针,所以我不计算每次迭代时T [i]的地址......我添加了两个方法一个返回指向已分配内存的指针,另一个返回指向结尾的指针。 要遍历一个整数数组,我必须写下这样的东西:

for(int * p = array.pData(); p != array.pEnd(); ++p){
  cout<<*p<<endl; 
}

然后,当我开始使用向量的向量时,我发现当有可能时,可以分配一大块内存而不是多次调用新内存。这时我将一个分配器添加到模板类中。

只有这样我才注意到我写了一个完全无用的std :: vector&lt;&gt;克隆。

至少现在我知道为什么我使用STL ......

答案 9 :(得分:3)

您可能对EASTL感兴趣,这是对STL电子艺术的重写。他们的设计决策主要是由多平台视频游戏编程中的特定需求/需求驱动的。链接文章中的摘要总结得很好。

答案 10 :(得分:3)

另一个缺点

如果你想在大学毕业后获得一份C ++工作,大多数想要招聘你的人都希望你熟悉标准C ++库。不一定非常熟悉实现级别,但肯定熟悉它的用法和习语。如果你以你自己的图书馆的形式重新实现轮子,你就会错过这个机会。尽管如此,如果您自己推出图书馆设计,您仍然可以学到很多东西,这可能会让您获得额外的布朗尼积分,具体取决于您的面试地点。

答案 11 :(得分:3)

缺点:

您正在引入对您自己的新库的依赖。即使这已经足够了,并且您的实现工作正常,您仍然具有依赖性。这可能会让您在代码维护方面苦苦挣扎。其他人(包括你自己,一年的时间,甚至一个月)都不熟悉你的独特字符串行为,特殊迭代器等等。在您开始重构/扩展任何内容之前,需要付出很多努力才能适应新环境。 如果你使用类似STL的东西,每个人都会知道它,它很好理解和记录,没有人必须重新学习你的定制一次性环境。

答案 12 :(得分:2)

缺点:你的大学课程可能是出于某种原因。事实上,你被它充满了烦恼(讽刺意图不是这样),可能表明你没有得到par,,并且当你进行范式转换时会受益匪浅。

答案 13 :(得分:1)

  

例如,使用STL吐出   难以理解和破坏的大量   编译错误

其原因主要是C ++模板。如果您使用模板(如STL那样),您将获得r 不可理解的错误消息。因此,如果您实现自己的基于模板的集合类,那么您将无法获得更好的位置。

您可以创建基于非模板的容器并将所有内容存储为void指针或某些基类,例如但是你会失去编译时类型检查而C ++很糟糕。这样做并不像在例如它那样安全。 Objective-C,Python或Java。其中一个原因是C ++没有所有类的根类来对所有对象进行所有内省,并且在运行时没有基本的错误处理。相反,如果您对该类型有误,您的应用可能会崩溃并烧毁,并且您不会得到任何错误的线索。

答案 14 :(得分:1)

缺点:重新实现所有(即质量很高)肯定会吸引一些优秀的开发人员几年。

答案 15 :(得分:1)

为什么不看看现有的C ++库。当C ++不那么成熟时,人们经常编写自己的库。看看Symbian(虽然非常可怕),Qt和WxWidgets(如果内存为我服务)有基本的收藏和东西,可能还有很多其他的。

我的观点是,STL的复杂性源于C ++语言的复杂性,而且除了使用更明智的命名约定之外,你几乎无法改进STL。我建议只要切换到其他语言,或者只是处理它。

答案 16 :(得分:1)

<强>优势

如果你研究一下MFC,你会发现你的建议已经在生产代码中使用了 - 并且已经存在了很长时间。 MFC的集合类都不使用STL。

答案 17 :(得分:0)

STL非常复杂,因为它需要用于通用库。

STL就是这样的原因:

  • 基于交互者,因此标准算法只需要针对不同类型的容器进行单一实现。
  • 专为在例外情况下正常行事而设计。
  • 在多线程应用程序中设计为'线程'安全。

在很多应用程序中,你真的有足够的以下内容:

  • string class
  • O(1)查找的哈希表
  • vector / array with sort /和binary search for sorted collections

如果您知道:

  • 您的课程不会在构造或作业上抛出异常。
  • 您的代码是单线程的。
  • 您不会使用更复杂的STL算法。

然后你可以编写自己的更快的代码,使用更少的内存并产生更简单的编译/运行时错误。

没有STL的更快/更容易的一些例子:

  • 使用引用计数字符串缓冲区的写时复制字符串。 (不要在多线程环境中执行此操作,因为您需要锁定引用计数访问权。)
  • 使用好的哈希表而不是std :: set和std :: map。
  • 可以作为单个对象传递的'Java'样式迭代器
  • Iterator类型,不需要知道容器的类型(为了更好的编译时间解耦代码)
  • 具有更多实用功能的字符串类
  • 向量容器中的可配置边界检查。 (所以不是[]或.at,而是带有编译或运行时标志的相同方法,用于从“安全”模式进入“快速”模式)
  • 容器,用于处理将删除其内容的对象的指针。

答案 18 :(得分:0)

看起来你更新了这个问题所以现在真的有两个问题:

  1. 如果我认为std :: library对我的需求来说过于复杂,我该怎么办?
  2. 设计自己的类,在内部使用相关的std :: library功能为您做“繁重的工作”。这样你就可以减少错误,你仍然可以创建自己的编码界面。

    1. 如果我想了解数据结构的工作原理,我该怎么办?
    2. 从头开始设计您自己的一组数据结构类。然后试着弄清楚为什么标准的更好。

答案 19 :(得分:0)

  

对于C ++中的大多数现有功能而言,“滚动我自己”有什么危险,可能的缺点和可能的优势?

你能负担得起并且可能证明重新发明轮子所付出的努力/时间/金钱的数量是多少?

  

重新使用提升或类似。

相当奇怪,你不能使用Boost。 IIRC,大量的贡献来自与大学相关/工作的人(想想Jakko Jarvi)。使用Boost的好处太多了,无法在此列出。

  

不要'重新发明轮子'

缺点:当你学到很多东西时,当你想到你真正的项目目标是什么时,你也会让自己退缩。

优势:对于要继承此权限的人来说,维护更容易。