繁体   English   中英

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

[英]casting comparison between Objective-C and C++

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

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

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

查看问题的答案 关于每种演员的意义。

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

C ++更注重类型安全而不是C. 许多演员操作符被添加以使许多不同的演员意图清晰 (并且由于其丑陋的形式而阻止人们使用它)。 和,

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

  • 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 } 

看一下CPlusPlus.com的文章,它详细介绍了各种类型转换方法。

  1. reinterpret_cast将任何指针类型转换为任何其他指针类型,甚至是不相关的类。 操作结果是从一个指针到另一个指针的值的简单二进制副本。 允许所有指针转换:既不检查指向的内容,也不检查指针类型本身。
  2. static_cast可以执行指向相关类的指针之间的转换,不仅可以从派生类到其基类,还可以从基类到其派生类。 这确保了如果转换了正确的对象,至少类是兼容的,但是在运行时期间不执行安全检查以检查被转换的对象实际上是否是目标类型的完整对象。
  3. dynamic_cast只能用于指针和对象的引用。 其目的是确保类型转换的结果是所请求类的有效完整对象。
  4. const_cast是一种类型的转换,它操纵对象的常量,要么被设置要么被删除。 例如,为了将const参数传递给期望非常量参数的函数

从广义上讲,它们允许程序员声明他们的意图并确切地断言他们试图通过强制转换实现的目标。 它们还有助于在编译时标记出错错误,否则只会在运行时显示(如果你很幸运!)。

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

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM