使用C ++但不使用语言的特定功能时,应该切换到C吗?


16

在业余时间,我正在开发NES模拟器作为一种爱好。我之所以使用C ++,是因为它是我最常使用,最常了解和最喜欢的语言。

但是,既然我在项目中取得了一些进步,我意识到我几乎没有使用C ++的任何特定功能,并且可以在普通C语言中完成并获得相同的结果。我不使用模板,运算符重载,多态性,继承。那你会说什么 我应该留在C ++还是用C重写?

我不会这样做来获得性能,它可能会产生副作用,但是想法是为什么在不需要C ++时为什么要使用C ++?

我正在使用的C ++的唯一功能是用于封装数据和方法的类,但是可以使用结构和函数来完成,我正在使用new和delete,但也可以使用malloc和free,我仅将继承用于回调,这可以通过指向函数的指针来实现。

请记住,这是一个业余项目,我没有截止日期,因此需要重写的开销时间和工作不是问题,也可能很有趣。那么,问题是C还是C ++?


3
在我看来,您已经回答了自己:如果只需要C,为什么要使用C ++?在许多情况下,C都可以正常运行。
乔治

3
@Giorgio:它们在最初的六十秒后都消失了,您需要维护代码。
DeadMG

7
I use C++ because is the language I use mostly, know mostly and like mostly.这就是您问题的答案。仅当当前语言无法解决问题时,才应在项目中切换语言。I don't use templates, operator overloading, polymorphism, inheritance.学习和使用这些概念比切换到C语言要有价值得多。既然这是一个业余项目,为什么不使用一些您以前从未使用过的东西呢?您总是可以使用C启动另一个项目并学习该语言,但是对于您当前的项目,切换是没有意义的。
yannis 2011年

4
我也不在我编写的每个项目中都使用100%的语言。您最了解C ++,您可能会发现有充分的理由使用以前从未发现过的功能。你可以开始治疗C ++作为一个更安全的C,一旦你开始使用标准库的东西,升压结构,如std::shared_ptrstd::unique_ptrboost::scoped_ptrstd::vectorstd::dequestd::map,等回调函数,看进用仿函数,并且在C ++ 11,你也可以开始使用lambda函数之类的东西。
wkl 2011年

3
@乔治:是的。滚动无限链表势必会产生不必要的错误。
DeadMG

Answers:


40

您现在还没有使用它,但下一次你泄漏内存或者得到一个双删除,你会被乞讨回来std::vector<T>std::unique_ptr<T, Del>并且std::shared_ptr<T>,它可以解决这些问题easily-几乎平凡。最终,这就是每个在C ++上使用C语言的人都会发生的事情,而更聪明的人只是不等bug出现后再进行迁移。

直接使用newdelete直接不属于C ++的代码,它属于我们称为“带有类的C”的那种半房子。那是大约1985年的语言。它与大约在2011年的C ++并不特别相似。很可能,无论您在哪里学到C ++都不能很好地教它-不幸的是,这很普遍-且受过更好的教育,您查找使用这些功能。

具体地说,正如我上面列出的,C ++的通用数据结构和资源管理类从根本上大大优于C所提供的任何东西。如果要动态分配数组,请使用std::vector<T>。那是一个很普通的用例。如果您不使用它们,那么您的代码将不必要地面临巨大的错误风险,尤其是与资源管理相关的错误。C ++可以保证安全性并以C永远不会碰到的方式重用代码。

但是,我认为您也可能期望过高。编写模板和操作符重载对于库使用者来说并不常见。如果您的代码使用std::vector<T>,则无需编写模板即可实现这一目标。如果您的代码使用std::string,则没有人会强迫您重载运算符。你只需要做的那些事情 std::vector<T>std::string-但你仍然可以把他们的优势。

多态性/继承也仅具有特定的用例。如果您的代码碰巧不需要您编写任何模板或使用虚函数,则不需要这样做,并且在某些程序或程序段中无需编写自己的模板。

而且,C语言的性能也不会超过C ++。


1
@Giorgio:make_shared存在,您可以编写make_unique完成相同工作的简单模板。比较安全
DeadMG

4
好答案。钉在头上。对于我们应该一直使用的这些小库,C ++最有价值。
Andres Jaan Tack

2
@Giorgio:这是不安全的,因为当调用这样的多个参数时,在发生异常的情况下可能会发生内存泄漏,并且make_shared效率更高。只有工厂功能才能提供保证的异常安全。
DeadMG

6
@ tp1:WT​​F?请用英文。
DeadMG 2011年

2
@Lohoris您无需引用即可获得常识。C应该以哪种方式比C ++更有性能?
克里斯说,请恢复莫妮卡(Monica)


6

我会从另一个方向看。通过用C重写代码,您可以获得任何好处吗?即使在纯粹的业余爱好者项目中,这样的重写也要付出一定的代价。如果没有别的,我想这就是机会成本-即,如果您不浪费时间用C重写它,那时候您可以做的其他事情。

底线:除非您认为该代码确实有可能在某些对C ++的访问受到限制(或根本不存在)的环境中使用,否则充其量是最好的时间浪费。至少在我的经验,它通常远远超出了非常迅速-在代码中,我用C ++写的是回想起不得不转换为C,我可以很清楚地记得,即使在相当多的情况下,它似乎像这应该是微不足道的,我使用的C ++特有的功能比我最初意识到的要多。要完全有希望发挥作用,您几乎必须将目标定为C89 / 90,在这种情况下,您会很快想起诸如必须在块的开头定义所有变量,而不是在实际位置定义变量的事情。用过的。

简而言之,除非您非常确定用C重写会带来真正的好处,否则几乎不可避免地会有很多更好的事情要做。


+1前一段时间,我不得不编写一个库以供另一个C项目使用,我认为也可以在C中实现它是一个好主意,我当时是个愚蠢的白痴。
克里斯说莫妮卡(Monica)

1

作为更一般的答案:

不要仅仅因为使用某些更独特的功能而切换到C ++。有一天,您可能需要这些功能,并且由于使用C语言,您会头疼。


1

对于业余爱好开发,我会考虑切换回纯C。微小的业余爱好开发模块更可能支持C和类似C的语言。

这里的许多答案可能来自专业软件类型。作为业余爱好者,您不会连续或全职进行编码。因此,如果您将项目提交表格的时间长达一年,然后考虑编码后的习惯,然后再尝试阅读您的代码,那么考虑一下您更可能会记住或忘记其中一种怪癖的语言。具有更丰富功能集的C ++,可能需要花费更多或更少的时间才能重新获取,具体取决于您的编码风格。


1

回答您的问题并不容易,因为我们不知道您是否在从事该项目的工作,以提高您的语言特定技能(C vs C ++)或提高其他编程技能(设计,解决问题等)。

“我正在使用的C ++的唯一功能是用于封装数据和方法的类,但是使用结构和函数也可以做到这一点,”。这不是真的。structsC语言中的C语言不支持封装并且不能包含函数(方法)-至少不使用诸如函数指针之类的技术。同样,C语言中的函数较弱,因为它们无法重载。

“我正在使用new和delete,但也可以使用malloc和free,并且我仅将继承用于回调,这可以通过指向函数的指针来实现。” 如deadmg提到的,使用直接newdelete在C ++中没有鼓励。而且,仅当需要多态时,才应首选OOP中的IMHO(和GoF)继承而不是组成。而且我认为使用函数指针在C语言中实现多态性(后期绑定)并不容易。

除此之外,我不会试图说服C ++比C语言“更好”,因为这是优先选择的问题,它始终取决于您要解决的问题(使用OOP功能开发NES仿真器可能会一个好主意)。


1
structs实际上,C语言中的C语言可以用于封装方法。您只需创建函数指针的结构,然后将其初始化以指向所需的任何函数即可。看看lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598为例。
罗伯特·马丁

那就对了。感谢您的评论,我扩展了答案。
sakisk

真好 nit:C中的函数可以重载(认为printf),但这样做会丢失任何类型检查。没有一种方法可以接受一组有限的可接受的声明:它要么为1(并且您将进行类型检查),要么为“很多”(并且丢失所有类型检查,风险自负)。与C语言中的大多数内容一样,这是可能的,但通常令人不舒服。
罗伯特·马丁

函数指针是高级C技术吗?真?
Donal Fellows 2012年

@DonalFellows你说的对,我夸张了。已删除高级... :)
sakisk 2012年

0

我是一个初学者,所以这里是我的2位。

我正在Wibit.net上通过一些不错的基本视频教程来学习C和C ++,也许它们可以为您提供很多“情况”的概述(而不是广告!)。

我建议您改用C,只是为了学习,因为您是一个业余爱好者,这将是一种乐趣,而不是问题。

我建议更多。用两种语言都可以做到。比较您将找到和使用的方式和解决方案。我相信这不会像您期望的那么“容易” ...但是您一定会学到很多东西!


1
非常感谢您,但是我没有学习,我已经了解C和C ++,我想问这个特定项目使用哪个。
Petruza

哎呀,我有时间学习!= P
H_7 2012年

1
另外,我建议您获得Kernigan和Stroustrup的书,而不是视频教程,它是一本不错的IDE(Visual Studio,Eclipse,Xcode),并通过对示例进行编码,反复试验和采用stackoverflow进行学习。
Petruza

-1

以下是C ++与C的优缺点:

  1. 移至C可以更轻松地保留在选定的C ++子集中,因为当您不使用C ++子集时,编译器将给出错误信息。如果主要问题是停留在确定的子集中,则应选择此替代方法。(为什么我们没有为此提供编译器支持?)
  2. 一旦您可以停留在选定的c ++功能子集内,那么下一步就是尝试更改子集,以摆脱破坏代码的不良约定。这需要使用整个c ++。
  3. 一旦您拥有了“停留在子集内部”和“这是一个很好的子集”,然后移出c ++功能,并开始考虑需求。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.