Objective-C 和 C + + 有什么不同?

Objective-C 和 C + + 在语法、特性、范例、框架和库方面的主要区别是什么?

* 重要提示: 我的目标不是在两种语言之间挑起性能大战。我只想要真实的事实。事实上,我的问题与表现无关!请给出任何可能看起来主观的资料来源。

176161 次浏览

与 C + + 相比,Objective C 与 Smalltalk 有更多的共同之处(实际上,除了语法之外)。

虽然它们都植根于 C 语言,但它们是两种完全不同的语言。

一个主要的区别是 Objective-C 专注于分派的运行时决策,并且在很大程度上依赖于它的运行时库来处理继承和多态性,而在 C + + 中,重点通常放在静态、编译时和决策上。

关于库,您可以在两种语言中使用普通的 C 库——但是它们的本机库是完全不同的。

不过有趣的是,您可以混合使用这两种语言(有一些限制)。

一些主要差异的简短列表:

  • C + + 允许多重继承,Objective-C 不允许。
  • 与 C + + 不同,Objective-C 允许命名方法参数,方法签名只包括参数的名称和类型以及返回类型(参见下面 bbum 和 Chuck 的注释)。相比之下,C + + 成员函数签名包含函数名以及参数/返回值的类型(没有它们的名称)。
  • C + + 使用 booltruefalse,Objective-C 使用 BOOLYESNO
  • C + + 使用 void*nullptr,Objective-C 更喜欢使用 idnil
  • Objective-C 使用“选择器”(类型为 SEL)作为函数指针的近似等价物。
  • Objective-C 使用一个消息传递范例(la Smalltalk) ,在这里您可以通过方法/选择器向对象发送“消息”。
  • Objective-C 将很乐意让您向 nil发送消息,而不像 C + + ,如果您尝试调用 nullptr的成员函数,它将崩溃
  • Objective-C 允许克劳斯·福尔曼,允许在运行时确定对消息的响应类,不像 C + + 那样,方法调用的对象必须在编译时知道(参见 wilhelmtell 下面的评论)。这与前面的观点有关。
  • Objective-C 允许使用“属性”为成员变量自动生成访问器。
  • Objective-C 允许分配给 self,并允许类初始化器(类似于构造函数)返回一个完全不同的类(如果需要的话)。与 C + + 相反,如果您创建一个类的新实例(在堆栈上隐式创建,或者通过 new显式创建) ,它保证是您最初指定的类型。
  • 类似地,在 Objective-C 中,其他类也可能在运行时动态地更改目标类以拦截方法调用。
  • Objective-C 缺乏 C + + 的名称空间特性。
  • Objective-C 缺乏与 C + + 引用等价的内容。
  • Objective-C 缺少模板,更倾向于(例如)允许在容器中进行弱类型化。
  • Objective-C 不允许隐式方法重载,但是 C + + 允许。也就是说,在 C + + int foo (void)int foo (int)中定义了方法 foo的隐式重载,但是要在 Objective-C 中实现同样的重载,需要显式重载 - (int) foo- (int) foo:(int) intParam。这是因为 Objective-C 的命名参数在功能上等同于 C + + 的名称错位。
  • Objective-C 会很高兴地允许一个方法和一个变量共享相同的名称,不像 C + + 通常会有适合的名称。我想这与 Objective-C 使用选择器而不是函数指针有关,因此方法名实际上没有“值”。
  • Objective-C 不允许在堆栈上创建对象——所有对象都必须从堆中分配(要么显式地使用 alloc消息,要么隐式地使用适当的工厂方法)。
  • 与 C + + 一样,Objective-C 同时具有结构和类。然而,在 C + + 中,它们的处理方式几乎完全相同,在 Objective-C 中,它们的处理方式则大相径庭——例如,您可以使用 可以在堆栈上创建结构。

在我看来,最大的区别可能是语法。你可以在任何一种语言中实现基本相同的功能,但是在我看来,C + + 语法更简单,而 Objective-C 的一些特性使得某些任务(比如 GUI 设计)由于克劳斯·福尔曼而变得更容易。

也许还有很多我错过的事情,我会更新我想到的任何其他事情。除此之外,可以高度推荐 LiraNuna 指给你的指南。顺便说一下,另一个感兴趣的网站可能是 这个

我还应该指出,我自己才刚刚开始学习 Objective-C,因此上面的许多内容可能并不完全正确或完整——如果是这样的话,我表示歉意,并欢迎提出改进建议。

编辑: 更新以解决以下评论中提出的问题,在列表中增加了一些项目。

我第一时间想到的是:

  1. 样式-Obj-C 是动态的,C + + 是 典型的静电干扰
  2. 虽然他们都是 OOP,我是 解决方案肯定是 与众不同。
  3. 不同的对象模型(C + + 是 受其编译时类型的限制 系统)。

对我来说,最大的不同是模型系统。Obj-C 允许您进行消息传递和自省,但是 C + + 拥有非常强大的模板。

每个人都有自己的长处。

Objective-C 是 C 的一个更完美的超集。在 C 和 Objective-C 中,允许从 void*到 struct 指针的隐式转换。

Foo* bar = malloc(sizeof(Foo));

除非显式强制转换 void指针,否则 C + + 不会编译:

Foo* bar = (Foo*)malloc(sizeof(Foo));

这与日常编程的相关性为零,只是一个有趣的琐碎事实。

正如其他人所说,Objective-C 在如何看待对象方面比 C + + 相当静态的领域更加动态。

Objective-C 属于面向对象语言的 Smalltalk 沿袭,它的对象概念与 Java、 Python 和其他“标准”、非 C + + 面向对象语言非常相似。很多克劳斯·福尔曼没有运算符重载到处传递信息。

C + + 本身就是一种奇怪的动物; 它基本上跳过了家族树的 Smalltalk 部分。从某些方面来说,它有一个很好的模块系统,支持继承,恰好可以用于面向对象程序设计。事情更加静态(例如,可重写的方法不是默认方法)。

Obj-C 在语言本身中具有更多的动态能力,而 C + + 更关注具有一些动态能力的编译时能力。

在 c + + 中,参数多态在编译时被检查,而在 Obj-C 中,参数多态是通过克劳斯·福尔曼实现的,而不是在编译时被检查。

Obj-C 在本质上是非常动态的。可以在运行时向类中添加方法。此外,它还在运行时进行自省以查看类。在 C + + 中,类的定义不能改变,所有的内省都必须在编译时完成。尽管可以使用函数映射(或类似的东西)在 C + + 中实现 Obj-C 的动态特性,但它仍然比 Obj-C 更加详细。

在 C + + 中,可以在编译时执行更多的检查。例如,使用变量类型(如联合) ,编译器可以强制编写或处理所有案例。这样你就不会忘记处理问题的边缘情况。然而,所有这些检查在编译时都是有代价的。Obj-C 的编译速度比 C + + 快得多。