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?
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. I was recently introduced to C++'s various casting operators reinterpret_cast, static_cast, dynamic_cast, and 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. (Been mostly a C person until then). I'm trying to understand why C++ seems to have all this complexity. Or to put it another way, what's Objective-C missing that it doesn't seem to have (or need?) this many casting types?
The main difference in C and Objective C is that C is a procedure programming language which doesn't support the concepts of objects and classes and Objective C is Object-oriented language which contains the concept of both procedural and object-oriented programming languages.
Objective-C is slightly slower than straight C function calls because of the lookups involved in its dynamic nature.
Syntactically, Objective-C is an extension of C. So, some portion of Objective-C is exactly the same as C. Your experience of C would help learning such aspect of Objective-C. But the core part of Objective-C programming is made of Object Oriented class system, which you cannot find in C.
While most of existing iOS apps are written in Objective-C, it's time to think about moving them to Swift.
See this answer to the question When should static_cast
, dynamic_cast
and reinterpret_cast
be used? 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?
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). 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 instances always use dynamic typing, so dynamic_cast
is not needed. (Type checking in ObjC is usually done with -isKindOfClass:
.)
static_cast
and reinterpret_cast
are the same in C, but not so in C++. Because C++ supports multiple inheritance (missing in ObjC), a pointer casting is not as simple as a 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
}
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
. 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
. If you try const void* p; reinterpret_cast<char*>(p)
, you'll get an error.
dynamic_cast
is needed to reliably downcast things (with a runtime check), and also for cross-casts (i.e. 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").
static_cast
is the rest of it - value conversions (int<->float etc), upcasting of object pointers/references, and unchecked downcasting. 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.
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.
Now as to why Obj-C doesn't "need" them. 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. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With