【问题标题】:How different is Objective-C from C++? [closed]Objective-C 与 C++ 有何不同? [关闭]
【发布时间】:2010-03-15 04:14:01
【问题描述】:

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

*重要提示:我的目标不是在两种语言之间引发性能战。我只想要真实的事实。事实上,我的问题与性能无关!请提供任何看似主观的东西的来源。

【问题讨论】:

  • This guide 给出了我见过的最好的比较。
  • @Oskar Kjellin:Mac 和 LiraNuna 的答案都是极好的答案。我无法客观地决定哪一个是最好的,因为他们两个都是互补的答案。
  • @Alerty 我知道(我自己也经常遇到这种情况)。也许只是将最重要的标记为已回答,这是我无法决定时所做的。我不喜欢没有标记为已回答的问题:(
  • 在第一个答案中添加第二个答案的链接,反之亦然

标签: c++ objective-c


【解决方案1】:

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

  • C++ 允许多重继承,Objective-C 不允许。
  • 与 C++ 不同,Objective-C 允许命名方法参数,并且方法签名仅包括参数的名称和类型以及返回类型(请参阅下面的 bbum 和 Chuck 的 cmets)。相比之下,C++ 成员函数签名包含函数名称以及参数/返回的类型(不包括它们的名称)。
  • C++ 使用booltruefalse,Objective-C 使用BOOLYESNO
  • C++ 使用void*nullptr,Objective-C 更喜欢idnil
  • Objective-C 使用“选择器”(类型为 SEL)作为函数指针的近似等效项。
  • Objective-C 使用消息传递范例(类似于 Smalltalk),您可以在其中通过方法/选择器向对象发送“消息”。
  • Objective-C 很乐意让你向nil 发送消息,不像C++,如果你尝试调用nullptr 的成员函数会崩溃
  • Objective-C 允许动态分派,允许响应消息的类在运行时确定,这与 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 为您指出的指南。顺便说一句,另一个感兴趣的站点可能是this

我还应该指出,我自己刚刚开始学习 Objective-C,因此上述很多内容可能并不完全正确或不完整 - 如果是这种情况,我深表歉意,并欢迎提出改进建议。

编辑:更新以解决以下 cmets 中提出的问题,在列表中添加了更多项目。

【讨论】:

  • 体面的名单;一更正。它们不是“命名参数”,而是“交错参数”。命名和“关键字参数”会导致混淆,认为方法名称的某些子集可能会被省略。它不能。
  • 您忘了列出最重要的区别:Object-C 使用动态调度,而 C++ 使用静态调度。换句话说,由 Objective-C 编译器编译的代码将具有负责响应在运行时确定的消息的类;由 C++ 编译器编译的代码会在编译时计算和编译此信息。
  • @wilhelmtell:C++ 编译器在编译时只知道超类。在运行时,实际的类可以是任何后代。这也是动态调度的一种形式,但与 Objective C 中使用的形式不同。请注意那些技术术语!
  • +1 好列表。然而,Objective-C 也使用void*NULL,只是不用于对象。您可以在 Obj-C 中使用任何 C 风格的指针,并且许多 API 调用实际上是通过引用传递或返回值,在这种情况下经常使用 NULL
  • @wilhelmtell - 我不知道有关 Objective-C 的任何信息,但在 C++ 中,您可以动态地让不同的类响应函数调用,但您需要有一个指针数组之类的东西基类,然后是“挂”在它上面的 ACTUAL 类。虽然所有类都需要有子类,但方法调用将在运行时根据类调用不同的方法。
【解决方案2】:

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

一个主要区别在于,Objective-C 专注于调度的运行时决策,并且严重依赖其运行时库来处理继承和多态性,而在 C++ 中,重点通常在于静态、编译时间和决策。

关于库,您可以在两种语言中使用纯 C 库 - 但它们的本地库完全不同。

有趣的是,您可以混合使用两种语言(有一些限制)。结果称为Objective-C++

【讨论】:

【解决方案3】:

在我的头顶:

  1. 样式 - Obj-C 是动态的,C++ 是 通常是静态的
  2. 虽然它们都是 OOP,但我是 某些解决方案将是 不同。
  3. 不同的对象模型(C++ 是 受其编译时类型的限制 系统)。

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

各有所长。

【讨论】:

    【解决方案4】:

    它们完全不同。与 C++ 相比,Objective C 与 Smalltalk 的共同点更多(嗯,除了语法,真的)。

    【讨论】:

      【解决方案5】:

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

      Objective-C 属于 Smalltalk 的面向对象语言,其对象概念与 Java、Python 和其他“标准”非 C++ 面向对象语言的概念非常相似。大量动态调度,没有运算符重载,到处发送消息。

      C++ 本身就是一种奇怪的动物。它主要跳过了家谱的 Smalltalk 部分。在某些方面,它有一个很好的模块系统,支持继承,恰好可以用于面向对象的编程。事情更加静态(例如,可覆盖的方法不是默认的)。

      【讨论】:

        【解决方案6】:

        Objective-C 是 C 的更完美超集。在 C 和 Objective-C 中,允许从 void* 隐式转换为结构指针。

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

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

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

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

        【讨论】:

        • 第二个例子不是 C++ 代码。当您尝试使用 C++ 编译器对其进行编译时,是 C 代码给您一个错误。如果您希望旧 C++ 与原始 C++ 接近,则可以编写 Foo* bar = reinterpret_cast< Foo* >(malloc(sizeof(Foo)); 然后可能使用就地构造函数。但截至今天,它的现代 C++ 更像 auto bar = new Foo(constructorArg); 实际上您不需要 malloc,并且无论是 callic,您都可以使用std::vector::reservestd::vector::emplace_mack
        【解决方案7】:

        Obj-C 在语言本身中具有更多的动态功能,而 C++ 更侧重于具有一些动态功能的编译时功能。

        在 C++ 中,参数多态是在编译时检查的,而在 Obj-C 中,参数多态是通过动态调度实现的,而不是在编译时检查。

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

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

        【讨论】:

        • 如果您要谈论价格,请保持公平!相反,Obj-C 在运行时解析动态方法调用比 C++ 慢得多。而且我认为与运行时速度相比,编译速度相对微不足道。我确信 Obj-C 因其更动态的调度而提供了许多好处,但也需要权衡取舍。
        • 诚然,运行时间与编译时间成本之间存在权衡。然而,编译时间并不总是微不足道的。在 C++ 中使用繁重的元编程和 EDSL 库(例如 Boost.Spirit)可以对编译时间产生巨大影响,同时在运行时生成非常快的代码。
        • 当然,相对于更简单的代码库的 POV,我过于简单化了......对于非常复杂的代码库,重新编译以测试小的更改可能会使开发变得非常乏味,这不是一件小事。但这真的可以在两者之间进行比较吗?这样依赖于 C++ 编译时特性的库能否在 Objective-C 中以某种方式重新构想并显示出编译速度更快?即“Obj-C 的编译速度比 C++ 快得多”是否是指可以测量可复制加速的等效代码库?否则,我们会比较种植苹果和橘子所需的时间。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多