24

在 C++ 中使用 C 不好?

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

我目前在一个论坛上,关于std::stringvs. a的争论char*正在发生。有人说分配一个简单的char*内存块效率更高,只要释放它就可以了。另一方面,我们有人说这std::string是优越的,因为它不涉及内存管理但效率较低。

所以这里的主要问题是:

  • 混合 C/C++ 不好?在编写 C++ 代码时是否应该只使用 100% C++?

任何答案将不胜感激!

4

12 回答 12

19

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

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

我会冒险猜测答案是否定的,因为编写这样的代码非常乏味,而且很难绝对确定这样编写的代码是正确的,即使在极少数失败的情况下也是如此。

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

编码 C++ 时是否应该只使用 100% C++?

是的,但是如果有一个 C 库可以满足您的需要,或者如果您有想要使用的遗留 C 代码,您当然可以使用该代码;一定要小心。与 C 代码互操作的最简洁的方法通常是围绕它编写一个 C++ 包装器。

于 2010-10-26T16:49:28.510 回答
13

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

于 2010-10-26T16:50:18.473 回答
9

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

在我看来,答案很简单:

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

两个主要例子:

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

  2. 使用基于 C 语言的 Win32 API 编写 C++ 程序。我说的是轻量级 API 使用,例如读取目录中的文件、检查文件是否存在等,而不是重度 GDI+ 或其他东西。我喜欢将 Win32 API 公开的所有 C 函数包装在漂亮的 C++ 样式函数中,可能带有必要的异常并返回 astd::string而不是必须将char*缓冲区作为参数传递。

我知道这两个例子都很……肤浅……但我觉得它们表达了一个足够笼统的想法。

于 2010-10-26T19:26:26.400 回答
5

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

这是可维护性的坏原因:
* C++ 程序员希望所有代码的行为都像 C++。
* C 程序员期望所有代码的行为都像 C。

因此,当你混合 C++ 和 C 时,你打破了程序员对事情应该如何工作的期望。

于 2011-10-19T09:23:56.373 回答
3

答案当然是:视情况而定。

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

如果你小心的话,使用 C 来提高性能是可以的。但是,只有在您知道自己需要性能的情况下,您才应该这样做。过早的低级优化是魔鬼的工作。

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

于 2010-10-26T16:56:23.570 回答
3

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

于 2010-10-26T20:48:28.320 回答
2

对 std::string vs char * 的参数进行重新分级。

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

于 2010-10-26T16:52:58.913 回答
1

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

于 2010-10-26T16:54:44.717 回答
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 idioms/styles/dangers 集成到 c++ 程序中更容易管理。

所以这里的主要问题是:混合 C/C++ 不好吗?当您编写 C++ 代码时,您是否应该只使用 100% C++?

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

于 2010-10-26T20:00:44.017 回答
1

stringvs的特定情况下,您应该对所有包含字符串常量(并且只有字符串常量)的变量const char *使用 bare ,仅在传递给需要. 始终如一地这样做可以消除大量的全局构造函数,不会引起内存分配问题(因为字符串常量是永久的、常量数据),而且 IMO 实际上使代码更清晰 - 你看,你知道这将是一个字符串常量。const char *stringstringconst char *

于 2010-10-26T20:12:28.073 回答
1

如果您在谈论技术,我会小心地说,执行上述操作是可以的。

使用 C 风格的程序组织技术编写 C++ 程序可能会导致许多可维护性问题。一般来说,程序员忽略了面向对象语言提供的许多好处。仅仅因为许多 C 语法是有效的 C++ 并且许多编码技术转移并不意味着您应该在 C++ 中执行它们。

也就是说,使用 C 函数和其他东西不是问题,只要你小心使用它们。在某些情况下,您必须这样做。

于 2010-10-26T20:28:32.340 回答
0

嗯,我的情况很奇怪。我正在开发一个应该在 C++ 中的系统(使用 C++ 编译器并使用术语 C++),但一切都是用 C 编写的。这非常令人沮丧,因为它已经到了我必须“证明”的地步' C++ 比 C 更好用,即使我们用 C++ 编码。当我介绍 std::string 时,一切都是地狱。我的看法是,现在一切都开始变得混乱(C 和 C++ 的混合)。很少有错误处理的例子。事实上,我想我可以数出 3 个系统范围的 try-catch 语句。代码很乱,内存泄漏很突出,发现错误是大海捞针。有数百行代码可以被 C++ 函数替换。我会说编写代码更高效、更简洁、更容易理解。

From my experience, yes of course you can mix C and C++. You can pretty much do whatever you want, but maintaining, debugging and actually figuring out what's going on becomes a problem. It's easy to say you're going to clean-up your memory allocations, but maybe someone else uses your code and doesn't. Maybe you forget to do it and you waste hours on finding silly bugs, instead of using that time to do something productive. I don't even think there should be an argument. When you do C++, do C++. When you do C, do C.

于 2014-05-22T10:07:10.157 回答