简体   繁体   English

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

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

Okay, so this might be a bit of an academic question. 好的,所以这可能是一个学术问题。 Can someone tell me if/how C++'s casting operators might translate to Objective-C... or how/why they're not necessary? 有人能告诉我C ++的投射操作符是否/如何转换为Objective-C ...或者如何/为什么它们没有必要?

I've been out of the loop with C++ for a few years now and it seems like every time I turn around they add a few new keywords. 我已经离开了几年的C ++循环,似乎每次我转身他们添加一些新的关键字。 I was recently introduced to C++'s various casting operators reinterpret_cast, static_cast, dynamic_cast, and const_cast. 我最近介绍了C ++的各种转换操作符reinterpret_cast,static_cast,dynamic_cast和const_cast。 I'm a little fuzzy on exactly when those situations come up that you would need to use all these types of casts. 当这些情况出现时你需要使用所有这些类型的演员表时,我有点模糊。

I've been using Objective-C for a year or two now and feel fairly comfortable with it. 我已经使用Objective-C一两年了,对它感觉相当舒服。 (Been mostly a C person until then). (直到那时候大部分都是C人)。 I'm trying to understand why C++ seems to have all this complexity. 我试图理解为什么C ++似乎具有所有这些复杂性。 Or to put it another way, what's Objective-C missing that it doesn't seem to have (or need?) this many casting types? 换句话说,什么是Objective-C缺少它似乎没有(或需要?)这么多的铸造类型?

See this answer to the question When should static_cast , dynamic_cast and reinterpret_cast be used? 查看问题的答案何时应该使用static_castdynamic_castreinterpret_cast on the meaning of each kind of casts. 关于每种演员的意义。

what's Objective-C missing that it doesn't seem to have (or need?) this many casting types? 什么是Objective-C缺少它似乎没有(或需要?)这么多的铸造类型?

C++ focuses a lot more in type safety than C. The many cast operators are added to make the many different casting intentions clear (and to discourage people from using it due to its ugly form). C ++更注重类型安全而不是C. 许多演员操作符被添加以使许多不同的演员意图清晰 (并且由于其丑陋的形式而阻止人们使用它)。 And, 和,

  • There is no const objects ( const NSObject* ) in Objective-C, and other const parameters aren't so emphasized unlike in C++, so const_cast is useless. 在Objective-C中没有const对象( const NSObject* ),并且与C ++不同,其他const参数没有那么强调,因此const_cast是无用的。

  • Objective-C instances always use dynamic typing, so dynamic_cast is not needed. Objective-C实例总是使用动态类型,因此不需要dynamic_cast (Type checking in ObjC is usually done with -isKindOfClass: .) (ObjC中的类型检查通常使用-isKindOfClass:

  • static_cast and reinterpret_cast are the same in C, but not so in C++. static_castreinterpret_cast在C中是相同的,但在C ++中却不是这样。 Because C++ supports multiple inheritance (missing in ObjC), a pointer casting is not as simple as a no-op: 因为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 } 

Have a look at the article on CPlusPlus.com which describes the various typecasting methods in detail. 看一下CPlusPlus.com的文章,它详细介绍了各种类型转换方法。

  1. reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes. reinterpret_cast将任何指针类型转换为任何其他指针类型,甚至是不相关的类。 The operation result is a simple binary copy of the value from one pointer to the other. 操作结果是从一个指针到另一个指针的值的简单二进制副本。 All pointer conversions are allowed: neither the content pointed nor the pointer type itself is checked. 允许所有指针转换:既不检查指向的内容,也不检查指针类型本身。
  2. static_cast can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived. static_cast可以执行指向相关类的指针之间的转换,不仅可以从派生类到其基类,还可以从基类到其派生类。 This ensures that at least the classes are compatible if the proper object is converted, but no safety check is performed during runtime to check if the object being converted is in fact a full object of the destination type. 这确保了如果转换了正确的对象,至少类是兼容的,但是在运行时期间不执行安全检查以检查被转换的对象实际上是否是目标类型的完整对象。
  3. dynamic_cast can be used only with pointers and references to objects. dynamic_cast只能用于指针和对象的引用。 Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class. 其目的是确保类型转换的结果是所请求类的有效完整对象。
  4. const_cast is a type of casting which manipulates the constness of an object, either to be set or to be removed. const_cast是一种类型的转换,它操纵对象的常量,要么被设置要么被删除。 For example, in order to pass a const argument to a function that expects a non-constant parameter 例如,为了将const参数传递给期望非常量参数的函数

Broadly speaking, they allow the programmer to declare their intent and assert exactly what they're trying to achieve by casting. 从广义上讲,它们允许程序员声明他们的意图并确切地断言他们试图通过强制转换实现的目标。 They also help flag up casting errors at compile time which would otherwise only show up at run time (if you're lucky!). 它们还有助于在编译时标记出错错误,否则只会在运行时显示(如果你很幸运!)。

I've not used objective C myself, so I can't comment on why that language might not have them. 我自己没有使用过目标C,所以我不能评论为什么那种语言可能没有它们。

Thing is, there are several broadly different categories of casts, with varying intent, and it is desirable to be able to explicitly specify that intent, so that you accidentally don't do the wrong thing. 事实上,有几种截然不同的类型的演员表,具有不同的意图,并且希望能够明确地指定该意图,以便您不小心做错了。 For example, you might be casting a const int* to const char* to operate on raw bytes, and unintentionally also drop the const . 例如,您可能正在将const int*const char*以对原始字节进行操作,并且无意中也会删除const Consequently, in C++, changing the pointer from one unrelated type to another is done with reinterpret_cast , while casting away const can only be done with const_cast . 因此,在C ++中,使用reinterpret_cast将指针从一个不相关的类型更改为另一个类型,而转换const只能通过const_cast完成。 If you try const void* p; reinterpret_cast<char*>(p) 如果你尝试const void* p; reinterpret_cast<char*>(p) const void* p; reinterpret_cast<char*>(p) , you'll get an error. const void* p; reinterpret_cast<char*>(p) ,你会收到一个错误。

dynamic_cast is needed to reliably downcast things (with a runtime check), and also for cross-casts (ie given a pointer of type Base1* to an object of actual type Derived which inherits from both Base1* and Base2* , to be able to cast directly to Base2* ; and the same for references - this is particularly useful for "interfaces"). 需要dynamic_cast来可靠地向下转换事物(使用运行时检查),并且还用于交叉转换(即,将Base1*类型的指针赋予实际类型Derived的对象,该对象继承自Base1*Base2* ,以便能够直接转换为Base2* ;对于引用也是如此 - 这对于“接口”特别有用。

static_cast is the rest of it - value conversions (int<->float etc), upcasting of object pointers/references, and unchecked downcasting. static_cast是其余部分 - 值转换(int < - > float等),对象指针/引用的向上转换以及未经检查的向下转换。 It is also the one used most often, though some style guides call for use of dynamic_cast on all object pointer/reference casts inasmuch as possible. 它也是最常用的,尽管一些样式指南尽可能在所有对象指针/引用强制转换上使用dynamic_cast

In general, the rationale seems to be: two most dangerous operations (casting to pointer-to-unrelated-type, and casting away constness) are provided with their own dedicated cast operators, to prevent any possibility of them occuring accidentally. 一般来说,理由似乎是:两个最危险的操作(投射到指针到无关类型,并抛弃常量)都有自己的专用投射操作符,以防止它们意外发生的任何可能性。 Following that, a new operator is provided for cases where the cast requires runtime lookup. 接下来,为演员需要运行时查找的情况提供了一个新的运算符。 Finally, yet another new operator is provided to cover any remaining ground. 最后,还提供了另一个新的操作员来覆盖任何剩余的地面。 The old, C-style "universal" casting operator is effectively deprecated. 旧的C型“通用”铸造操作员实际上已被弃用。

Now as to why Obj-C doesn't "need" them. 现在,为什么Obj-C不“需要”它们。 Arguably, it could actually use the difference between const_cast , reinterpret_cast and static_cast - but those were, apparently, seen as not adding enough value to extend the core C language. 可以说,它实际上可以使用const_castreinterpret_caststatic_cast之间的区别 - 但显然,这些差异被视为没有增加足够的值来扩展核心C语言。 It doesn't need dynamic_cast , because it doesn't have multiple inheritance (protocols are somewhat different), and type checks are done via isa method instead. 它不需要dynamic_cast ,因为它没有多重继承(协议有些不同),而类型检查则通过isa方法完成。

Where C (and Objective C) casts are heavy rubberized mallets, the C++ casts are a set of chisels. C(和物镜C)演员是重型橡胶槌,C ++演员是一组凿子。 They are there to allow you to declare the specific kind of cast you'd like to make, and let the compiler help you enforce that specific kind of cast only. 它们允许您声明您想要制作的特定类型的转换,并让编译器帮助您仅强制执行特定类型的转换。 Since casts can be dangerous, the limited scope of each of these casts makes them safer – and the more awkward syntax is touted as an advantage, since it works to discourage overuse of casts. 由于演员阵容可能是危险的,因此每个演员阵容的有限范围使他们更安全 - 而且更笨拙的语法被吹捧为一个优势,因为它可以阻止过度使用演员阵容。

The one that's quite different from Objective C is dynamic_cast , which does an additional runtime check to make sure the object is of the desired type before casting to it, and returning 0 or throwing an exception if it doesn't exist. 与Objective C完全不同的是dynamic_cast ,它执行额外的运行时检查以确保对象在转换为期望之前具有所需类型,并返回0或抛出异常(如果它不存在)。 It is similar to invoking isKindOfClass on an NSObject before doing an Objective C cast, and in the C++ world is very useful for downcasting. 它类似于在进行Objective C isKindOfClass之前在NSObject上调用isKindOfClass ,而在C ++世界中对于向下转换非常有用。 Note, however, that because of dynamic method dispatch in Objective C, you don't have to downcast an object before you can send it specific messages for its type, so the role of downcasting is less than it is in the C++ world. 但请注意,由于Objective C中的动态方法分派,您不必在向对象发送特定消息之前对其进行向下转换,因此向下转换的作用比在C ++世界中要小。

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

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