在Objective-C和C ++之间进行比较

时间:2010-06-30 07:18:10

标签: c++ objective-c casting

好的,这可能是一个学术问题。有人可以告诉我C ++的投射操作符是否/如何转换为Objective-C ...或者如何/为什么不需要它们?

我已经离开了几年的C ++循环,似乎每次我转身都会添加一些新的关键字。我最近介绍了C ++的各种转换操作符reinterpret_cast,static_cast,dynamic_cast和const_cast。对于那些你需要使用所有这些类型的演员表的情况,我有点模糊。

我已经使用Objective-C一两年了,对它感觉相当舒服。 (直到那时候大部分都是C人)。我试图理解为什么C ++似乎具有所有这些复杂性。换句话说,什么是Objective-C缺少它似乎没有(或需要?)这么多的铸造类型?

4 个答案:

答案 0 :(得分:9)

关于每种演员阵容的含义,请参阅this answer to the question When should static_cast, dynamic_cast and reinterpret_cast be used?

  

什么是Objective-C缺少它似乎没有(或需要?)这么多的类型?

C ++在类型安全方面的重点远远超过C. The many cast operators are added to make the many different casting intentions clear(并且由于其丑陋的形式而阻止人们使用它)。和,

  • 在Objective-C中没有const对象(const NSObject*),并且与C ++不同,其他const参数没有那么强调,所以const_cast没用。

    < / LI>
  • Objective-C实例始终使用动态类型,因此不需要dynamic_cast。 (ObjC中的类型检查通常使用-isKindOfClass:完成。)

  • static_castreinterpret_cast在C中是相同的,但在C ++中却不是这样。因为C ++支持多重继承(ObjC中缺少),所以指针转换并不像no-op那样简单:

    #include <cstdio>
    
    struct A {
        int x;
        A() : x(12) {}
    };
    struct B {
        int y;
        B() : y(33) {}
        int get() const { return y; }
    };
    struct C : A, B {
        int z;
        C() : A(), B(), z(41) {}
    };
    
    int main () {
        C* c = new C;
        printf("%d\n", c->get());                       // 33
        printf("%d\n", static_cast<B*>(c)->get());      // 33
        printf("%d\n", reinterpret_cast<B*>(c)->get()); // 12
    }
    

答案 1 :(得分:1)

查看详细描述各种类型转换方法的the article on CPlusPlus.com

  1. reinterpret_cast将任何指针类型转换为任何其他指针类型,即使是不相关的类也是如此。操作结果是从一个指针到另一个指针的值的简单二进制副本。允许所有指针转换:既不检查指向的内容,也不检查指针类型本身。
  2. static_cast可以在指向相关类的指针之间执行转换,不仅可以从派生类到其基类,还可以从基类到其派生类。如果转换了正确的对象,这可以确保至少类是兼容的,但是在运行时没有执行安全检查以检查被转换的对象实际上是否是目标类型的完整对象。
  3. dynamic_cast只能用于指针和对象的引用。其目的是确保类型转换的结果是所请求类的有效完整对象。
  4. const_cast是一种类型的转换,它操纵对象的常量,要么设置要么被删除。例如,为了将const参数传递给期望非常量参数的函数
  5. 从广义上讲,它们允许程序员声明他们的意图并确切地断言他们试图通过强制转换实现的目标。它们还有助于在编译时标记出现错误,否则只会在运行时显示(如果你很幸运!)。

    我自己没有使用过目标C,所以我不能评论为什么那种语言可能没有它们。

答案 2 :(得分:1)

事实上,有几种截然不同的类型的强制转换,具有不同的意图,并且希望能够明确指定该意图,以便您不小心做错了。例如,您可能会将const int*转换为const char*以对原始字节进行操作,并且无意中也会删除const。因此,在C ++中,使用reinterpret_cast将指针从一个不相关的类型更改为另一个类型,而转换const只能使用const_cast完成。如果您尝试const void* p; reinterpret_cast<char*>(p),则会收到错误。

需要

dynamic_cast来可靠地向下转换事物(使用运行时检查),并且还需要交叉转换(即,将Base1*类型的指针指向实际类型为Derived的对象继承自Base1*Base2*,以便能够直接转换为Base2*;对于引用也是如此 - 这对于“接口”特别有用。

static_cast是其余部分 - 值转换(int&lt; - &gt; float等),对象指针/引用的向上转换以及未经检查的向下转换。它也是最常用的,尽管一些样式指南要求尽可能在所有对象指针/引用强制转换上使用dynamic_cast

一般来说,理由似乎是:两个最危险的操作(转换为指针到无关类型,并抛弃常量)都有自己的专用转换操作符,以防止它们意外发生的任何可能性。接下来,为演员需要运行时查找的情况提供了一个新的运算符。最后,还提供了另一个新的操作员来覆盖任何剩余的地面。旧的C型“通用”铸造操作员实际上已被弃用。

现在为什么Obj-C不“需要”它们。可以说,它实际上可以使用const_castreinterpret_caststatic_cast之间的差异 - 但显然,这些差异似乎没有增加足够的价值来扩展核心C语言。它不需要dynamic_cast,因为它没有多重继承(协议有些不同),而类型检查则通过isa方法完成。

答案 3 :(得分:1)

当C(和物镜C)演员是重型橡胶槌时,C ++演员是一组凿子。它们允许您声明您想要制作的特定类型的转换,并让编译器帮助您仅强制执行特定类型的转换。由于演员阵容可能很危险,因此每个演员阵容的范围有限使他们更安全 - 而且更笨拙的语法被吹捧为优势,因为它可以阻止过度使用演员表。

与Objective C完全不同的是dynamic_cast,它会进行额外的运行时检查以确保对象在转换为期望之前具有所需类型,并返回0或抛出异常(如果它没有)存在。它类似于在进行Objective C强制转换之前在NSObject上调用isKindOfClass,而在C ++世界中对于向下转换非常有用。但请注意,由于Objective C中的动态方法调度,您不必在向对象发送特定消息之前对其进行向下转换,因此向下转换的作用比在C ++世界中要小。 / p>