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

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

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

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

所以这里的主要问题是:

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

任何答案将不胜感激!

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

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

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

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

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

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

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

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

在我看来,答案很简单:

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

两个主要的例子:

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

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

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

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

重新调整std :: string vs char *的参数。

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

答案当然是:这取决于。

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

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

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

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

这是可维护性的坏因素:
* C ++程序员希望所有代码都像C ++一样运行。
* C程序员希望所有代码都像C一样。

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

这里简单的答案是, 简介 ; 确定哪种方法最适合您的情况并明智地使用它!

在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 ++习语,而不会降低性能并且具有更好的可维护性。

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

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

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

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

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

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