在C ++代码中使用/混合C?

时间:2010-10-26 16:46:12

标签: c++ c memory-management mixing

在C ++中使用C是不是很糟糕?

很多人告诉我在C ++中使用C是不好的,因为它不那么安全,而且需要更多的内存管理。我一直告诉他们,只要你知道你在做什么,你删除你的“新”并释放你的“malloc”,那么C就不是问题了。

我目前正在论坛上发生std::stringchar*的争论。有些人说分配一个简单的char*内存块效率更高,只要你解除分配它就没问题了。另一方面,我们有人说std::string是优越的,因为它没有涉及内存管理,但效率较低。

所以这里的主要问题是:

  • 混合C / C ++不好吗?在编写C ++时,你是否只能使用100%C ++?

任何答案都将不胜感激!

12 个答案:

答案 0 :(得分:17)

  

我一直告诉他们,只要你知道你在做什么,然后你删除你的新东西并释放你的malloc,那么C就不是问题了。

这是真的;如果你非常小心并确保你手动清理,那么这不是问题。但你真的有时间这样做吗?每次调用new都可以抛出std::bad_alloc。您总是捕获每个可以抛出的异常并手动清理任何资源吗?

我很难猜测答案是“不”,因为编写这样的代码非常繁琐,而且很难确保代码编写是正确的,即使在罕见的情况下也是如此故障。

如果答案是“是”,那你为什么要浪费这么多时间来担心资源管理呢? C ++习语如范围绑定资源管理(SBRM;通常称为资源获取是初始化(RAII))和标准模板库之类的库可以帮助您更轻松地编写正确的代码。为什么在你不需要的时候会遇到困难?

  

编译C ++时,你是否只能使用100%C ++?

是的,但是如果有一个C库可以做你需要的东西,或者你有你想要使用的遗留C代码,你当然可以使用那些代码;一定要小心。通常,与C代码互操作的最简洁方法是在其周围编写C ++包装器。

答案 1 :(得分:12)

我坚信你的问题与C或C ++完全没有关系。你的问题是交易可疑的安全效率。是的,C可以更有效率。但效率更高?你为此付出了什么?这些是你应该回答的问题。在大多数情况下,字符串与const char *开销是不明显的。如果您正在开发一个效率极其关键的应用程序,那么为什么不首先在C中编写它?

答案 2 :(得分:7)

我对答案和评论中的两极分化感到非常惊讶。

在我看来,答案很简单:

  

编写C ++项目时,使用C ++,避免使用C(和系列)并坚持使用标准库和STL。确保一个同质的C ++接口(毕竟它是一个C ++项目!)   当在C中使用外部项目时,恰好用C语言编写,当然你可以使用它。 (见下面的例子)

两个主要的例子:

  1. 编写一个进行科学计算的C ++程序/库。我肯定会使用GSL(GNU科学库),它用C语言编写。只有一些注意事项(如GSL中特定结构和函数的专用初始化和自由函数),可以在{{1}中吸收} typedef。还存在错误处理的问题:如果需要/想要,可以在异常机制中抽象检查错误代码,或者可以保留计算函数中包含的错误代码。 GSL确实有一种设置错误处理程序的方法,我想其他一些C库都有这样的功能。

  2. 使用Win32 API编写C ++程序,这是一个非常基于C的程序。我在谈论轻量级API的使用,比如读取目录中的文件,检查文件是否存在等等,不是重GDI +或其他东西。我喜欢将Win32 API公开的所有C​​函数包装在漂亮的C ++样式函数中,可能包含必要的异常并返回std::unique_ptr而不必传递std::string缓冲区作为参数。

  3. 我理解这两个例子都很......很浅......但我觉得他们表达了一个足够普遍的想法。

答案 3 :(得分:4)

是的,混合C和C ++是不好的,任何原因都与性能或安全性无关:

这是可维护性的不良原因:
* C ++程序员希望所有代码都像C ++一样 * C程序员希望所有代码都像C一样。

因此,当你混合使用C ++和C时,你会破坏程序员对事情应该如何运作的期望。

答案 4 :(得分:3)

这里更好的问题是,为什么要使用C?表现?首先,我认为具有相同功能的程序没有可测量的性能差异。其次,您必须分析并证明对于您的特定情况,C ++较慢。第三,通过使用C而不是C ++,您放弃了大量的应用程序安全性。

答案 5 :(得分:2)

重新调整std :: string vs char *。

的参数

std :: string不会慢于char *(对于堆char *);许多实现都快得多,因为它们使用私有内存池。无论如何,std :: string的健壮性远远超过任何(不太可能的)性能

答案 6 :(得分:2)

答案当然是:这取决于。

通常,您希望避免混合可能导致混淆的事物,这可能会进一步导致难以发现的错误。仅仅因为“你知道你在做什么”并不意味着接触你代码的下一个人会知道你在做什么。如果你正在开发只有你会使用的代码,那么可能没问题,但情况很少。

如果你小心的话,使用C表示性能很好。但是,如果您知道自己需要性能,那么您应该这样做。过早的低级优化是魔鬼的工作。

这是一种非常罕见的情况,使用char * over std :: string会给你带来明显的性能优势,而且只有在确实存在的情况下,内存管理才值得麻烦。

答案 7 :(得分:1)

这里的简单答案是个人资料;确定哪些在你的案例中效果最好并明智地使用它!

答案 8 :(得分:1)

  

在C ++中使用C是不是很糟糕?

虽然是一个主观问题:在我看来,采取了很多措施来避免在c ++程序中使用c。

  

很多人告诉我在C ++中使用C是不好的,因为它不那么安全,而且需要更多的内存管理。我一直告诉他们,只要你知道你在做什么,你删除你的新东西并释放你的malloc,那么C就不是问题了。

你正在重新引入c ++旨在克服的缺陷和危险,而不是c ++程序中的事情。

我经常检查/拒绝/重写进入“c with c ++ features”或“c ++ with c features”的代码库的代码。我甚至可以将malloc,free等更改为在根命名空间(以及其他内容)中断言。

  

我目前正在一个论坛上发生关于std :: string与char *的争论。有些人说分配一个简单的char *内存块效率更高,只要你解除分配它就没问题了。另一方面,我们有人说std :: string是优越的,因为它没有涉及内存管理,但效率较低。

在c ++中表示字符串的选项多于std :: string。

在我看来,创建一个代表字符串并用于特定目的的新类或遵循其他合同(必要时)是完全有效的。当使用动态内存时,这些字符串表示的部分合同(当然)是使用new[]/delete[]管理自己的资源。

如果效率非常重要且std::string不是特定任务的理想选择,那么c ++就足以通过在c ++中创建专用接口来表达您对这些特定情况的意图。有很多情况下这是可以接受的(imo),但并不总是值得花时间投资。无论如何,它比将c成语/样式/危险集成到c ++程序中更容易管理。

  

所以这里的主要问题是:混合C / C ++是不是很糟糕?你的编码C ++时,你的ONLY应该只使用100%C ++吗?

最好根据您的需求创建可重用的基于对象的解决方案。所提供的示例中的危险可以完全封装(如果这种优化真的值得花时间投入),并且可以编写使用c ++习语,而不会降低性能并且具有更好的可维护性。

答案 9 :(得分:1)

stringconst char *的特定情况下,您应该对所有包含字符串常量的变量使用裸const char *(并且仅 < / em>字符串常量),仅在传递到需要string的API时才转换为string。一致地执行此操作可以消除大量的全局构造函数,不会导致内存分配问题(因为字符串常量是永久的,常量数据),IMO实际上使代码更清晰 - 您看到const char *,您知道这将是一个字符串恒定。

答案 10 :(得分:1)

如果你在谈论技巧,我会小心地说,做上述事情是可以的。

使用C风格的程序组织技术编写C ++程序可能会导致许多可维护性问题。通常,程序员忽略了面向对象语言提供的许多好处。很简单,因为大部分C语法都是有效的C ++,许多编码技术转移并不意味着你应该用C ++来实现它们。

那就是说,使用C函数和东西不是问题,只要你仔细考虑它们的使用。在某些情况下,你必须。

答案 11 :(得分:0)

嗯,我处于一种奇怪的境地。我正在研究一个应该是C ++的系统(使用C ++编译器并使用术语C ++),但是所有内容都是用C语言编写的。这非常令人沮丧,因为它已经到了我需要的地步&# 39;证明&#39;使用C ++比使用C语言更好,即使我们使用C ++进行编码也是如此。当我介绍std :: string时,一切都很糟糕。我对此的看法是,现在一切都开始混乱(C和C ++的混合)。很少有错误处理实例。事实上,我认为我可以计算3个系统范围的try-catch语句。代码很乱,内存泄漏很突出,发现错误是大海捞针。有数百行代码可以被C ++函数替换。我说编写代码更有效,更清晰,更容易理解。

根据我的经验,当然可以混合使用C和C ++。你几乎可以做任何你想做的事情,但维护,调试和实际弄清楚发生了什么变成了问题。很容易说你要清理你的内存分配,但也许其他人使用你的代码并没有。也许你忘了这么做而浪费时间去寻找愚蠢的错误,而不是利用那段时间来做一些富有成效的事情。我甚至不认为应该有争论。当你做C ++时,做C ++。当你做C时,做C。