无法在C中实现的C ++特性?

时间:2009-12-01 11:46:27

标签: c++ c

我已经读过C ++是C的超集,并通过创建对象提供实时实现。此外,C ++对现实世界是封闭的,因为它充满了面向对象的概念。

C ++中有哪些概念不能在C中实现?

  1. 有人说我们不能用C语言编写方法,那么我们怎样才能有printf()的不同风格呢? 例如,printf("sachin");将打印sachinprintf("%d, %s",count ,name);将打印1,sachin,假设count是一个整数,其值为1,name是一个初始化为"sachin"的字符数组。
  2. 有人说数据抽象是用C ++实现的,那么结构呢?

14 个答案:

答案 0 :(得分:23)

这里的一些响应者认为,使用C ++代码可以生成的大多数东西也可以用具有足够野心的C生成。在某些部分中也是如此,但除非您修改C编译器以偏离标准,否则某些事情本身是不可能实现的。

<强> Fakeable:

  • Inheritance(指向子结构中父级结构的指针)
  • 多态性(使用一组函数指针伪造vtable)
  • 数据封装(不透明的子结构,实现未在公共接口中公开)

<强>不能

值得一试:

  • GLib (一个C库)有一个相当精细的OO emulation
  • 我发布了一个 question ,一次是关于人们在使用C而不是C ++时最想念的内容。

对RAII的澄清:

这个概念在涉及其最重要的方面时通常被误解 - 隐式资源管理,即保证(通常在语言层面)资源得到妥善处理的概念。有些人认为实现RAII可以通过将此责任留给程序员来完成(例如,在goto标签上显式析构函数调用),遗憾的是,这并没有提供RAII作为设计概念的安全原则。

来自维基百科文章的一篇文章,阐明了RAII的这一方面:

“因此,资源需要与合适对象的生命周期联系起来。它们是在初始化期间获取的,当它们在可用之前不可能被使用时,并且在销毁相同对象时被释放, 即使出现错误也可以保证。“

答案 1 :(得分:11)

答案 2 :(得分:4)

关于哪些功能无法实现,更不用说语言中直接支持哪些功能,因此可以清晰简洁地表达设计。

当然,您可以在C中实现,模拟,伪造或模拟大多数C ++功能,但生成的代码可能不太可读或不可维护。对OOP功能的语言支持允许基于面向对象设计的代码比非OOP语言中的相同设计更容易表达。如果C是您选择的语言,那么通常OOD可能不是最好的设计方法 - 或者至少大量使用高级OOD习语可能并不可取。

当然,如果你没有设计,那么你很可能会以任何语言混乱! ;)

答案 3 :(得分:3)

  1. C标准库中只有一个printf()。其他变种是通过更改名称来实现的,例如sprintf()fprintf()等等。

  2. 结构无法隐藏实现,C中没有private数据。当然,您可以通过不显示数据来隐藏数据。指针指向,就像标准库对FILE *所做的那样。所以有数据抽象,但不是struct构造的直接特征。

  3. 此外,您不能在C中重载运算符,因此a + b总是意味着正在进行某种添加。在C ++中,根据所涉及对象的类型,任何事情都可能发生。

    请注意,这暗示(巧妙地)实际上+覆盖了is int + int;例如,float + int与{{1}}的代码不同。但是你不能自己做那种覆盖,它只适用于编译器。

答案 4 :(得分:3)

好吧,如果您不打算使用C实现C ++编译器,那么您可以使用C ++进行数千种操作,但不能使用C语言。仅举几例:

  • C ++有类。类具有构造函数和析构函数,它们在对象初始化或描述时自动调用代码(超出范围或使用delete关键字)。
  • 类定义层次结构。你可以扩展一个类。 (继承)
  • C ++支持多态性。这意味着您可以定义虚拟方法。编译器将根据对象的类型选择调用哪个方法。
  • C ++支持运行时信息。
  • 您可以在C ++中使用异常。

虽然您可以在C中模拟上述大部分内容,但您需要依赖约定并手动完成工作,而C ++编译器可以为您完成工作。

答案 5 :(得分:3)

你可以在C语言中完全实现C ++ ...来自AT + T的原始C ++编译器实际上是一个名为CFront的预处理器,它只是将C ++代码翻译成C并进行编译。

目前,comeau computing仍然使用这种方法,他们生成了大多数符合C ++标准的编译器之一,例如。它支持所有C ++功能。

答案 6 :(得分:2)

printf使用的是可变长度参数列表,而不是函数的重载版本

C结构没有构造函数,并且无法从其他结构继承它们只是解决分组变量的简便方法

C不是OO语言,也没有OO语言的功能

说过你可以用C代码模仿C ++功能,但是用C ++编译器会在编译时为你完成所有的工作

答案 7 :(得分:2)

所有其余的都是“轻易”伪造的:)

答案 8 :(得分:2)

  

C ++中有哪些概念   无法在C中实现?

这有点奇怪的问题,因为用C ++表示的任何概念都可以用C表示。甚至类似于C ++模板的功能也可以用C实现,使用各种{{3和其他危害人类罪。

真正的区别归结为两件事:编译器将同意执行的内容,以及语言提供的语法便利性。

关于编译器实施,在C ++中,编译器不允许您直接从类的外部或类的朋友访问私有数据成员。在C中,编译器不会强制执行此操作;您将不得不依赖API文档将“私有”数据与“可公开访问”的数据分开。

关于语法方便性,C ++提供了C中没有的各种便利,例如运算符重载,引用,自动对象初始化和销毁​​(以构造函数/析构函数的形式),异常和自动堆栈展开,构建 - 支持多态等等。

基本上,用C ++表达的任何概念都可以用C表示;它只是编译器将在多大程度上帮助您表达某个概念以及编译器提供多少语法便利性的问题。由于C ++是一种较新的语言,它带来了比你在C中找到的更多的花里胡哨,因此使得某些概念的表达更容易。

答案 9 :(得分:0)

与OOP无关的一个功能是default arguments,如果使用正确,它可以成为真正的击键保护程序。

答案 10 :(得分:0)

功能重载

答案 11 :(得分:0)

我认为名称空间很多,模板无法在C中实现。

答案 12 :(得分:-1)

不应该有太多这样的东西,因为早期的C ++编译器确实从C ++源代码生成C源代码。基本上你可以在汇编程序中做所有事情 - 但不想这样做。

答案 13 :(得分:-3)

引用Joel,我会说C ++的一个强大的“功能”是运算符重载。对我而言,这意味着拥有一种会让你疯狂的语言,除非你保持自己的代码。例如,

  

i = j * 5;

     

...在C中你知道,至少,j是   乘以五和   结果存储在i。

     

但如果你看到同样的片段   用C ++编写的代码,你什么都不知道。   没有。知道什么是唯一的方法   真正发生在C ++中的是找出答案   我和j是什么类型的东西   可能会在某处宣布   完全不同的。那是因为j   可能是一个有运算符的类型*   超载,它做了一些事情   当你尝试时非常机智   乘以它。而我可能是一个类型   有operator =重载,和   类型可能不兼容所以   自动类型强制函数可能   最终被召唤。唯一的方法   找出来的不仅是检查   变量的类型,但要找到   实现该类型的代码,以及   如果有继承,上帝会帮助你   在某个地方,因为现在你必须   在课堂上一路走来   层次结构都是你自己试图   找到代码的真正位置,以及是否   在某处有多态,你是   真的遇到了麻烦,因为事实并非如此   足以知道i和j的类型   声明,你必须知道什么类型   他们现在,可能   涉及检查任意数量   代码,你永远不会真的   确定你到处都是   感谢暂停问题(p!)。

     

当你在C ++中看到i = j * 5时,你就是   真的在你自己,bubby,那,   在我看来,降低了能力   只是通过检测可能的问题   看代码。

但同样,这是一个功能。 (我知道我会被修改,但在撰写本文时,只有少数帖子谈到了运算符重载的缺点)