Objective-C for C++ Programmers

I find it easier to learn something new when it is presented in the context of something with which I’m already familiar. For example, when learning gdb, I found Apple’s Technical Note TN2030: GDB for MacsBug Veterans quite helpful. For those Object-Oriented and C++ experts learning Objective-C, I’ll present some Objective-C concepts in the context of OO and C++ in hopes of making the transition easier.

While most of the syntax of Objective-C is based on C, it is clear that Objective-C is strongly influenced by Smalltalk. One example of Smalltalk’s influence is the dynamism of Objective-C. Objects in Objective-C are dynamically typed. Some C++ libraries, such as object-request brokers (ORBs), provide similar introspection functionality, but, in Objective-C, this functionality is a core part of the language and run-time. In addition, methods in Objective-C are dynamically bound. When a message is sent, the run-time examines the receiver of the message to find the specified selector and then invokes the method. While this is conceptually similar to the virtual function table in C++, the Objective-C approach is much more flexible. Unlike in C++, the selectors aren’t bound to a particular index at compile time; rather, they are assigned unique identifiers that are mapped to method addresses. Furthermore, the selector itself can be a variable that is defined at run-time. Yes, this is slower than making virtual function calls in C++. To mitigate this, the Objective-C run-time caches the selectors and method addresses as they are used. This dynamic binding is a huge benefit if you are developing a public framework. You will be able add new methods without worrying if you are breaking the framework’s current clients by changing the v-table layout.

Instance variables in Objective-C correspond to data members in C++. Objective-C uses the term outlet when describing instance variables that refer to other objects. There are two types of Objective-C outlets: intrinsic and extrinsic. An intrinsic outlet is a composition; that is, one objects owns the other. An extrinsic outlet is just an association. Class methods in Objective-C are static class methods in C++. Instance methods in Objective-C are non-static class methods in C++.

Almost every Objective-C object inherits either directly or indirectly from NSObject. The NSObject fulfills a similar purpose as IUnknown in COM or other object base classes in ORBs.

Objective-C provides a better, but not ideal, separation between interface and implementation than C++. Unfortunately, like in C++, instance variables still need to be declared in public headers. In addition, like in C++, you need to “pad” your class declaration with a place-holder instance variable if there is the possibility that additional instance variables may need to be added in the future. However, unlike in C++, you can at least declare private methods solely in the implementation file by using a private category.

Objective-C supports single inheritance and doesn’t support, unlike C++ multiple inheritance. I’m going to steer clear of claiming whether this is an advantage or disadvantage of Objective-C. Regardless, there are a number of features of Objective-C that diminish the lure of multiple inheritance. One, that I briefly mentioned above, is categories. Categories allow you to add additional methods to a class without having to subclass that class. These additional methods can be, and almost always are, declared in a completely different header than the one that declares the class. In fact, the implementation of the class that you are extending with a category doesn’t even need to be available. Another feature is protocols. There are two types of protocols: formal and informal. A formal protocol is most similar to a C++ class that contains nothing but pure virtual methods (i.e., an interface). Classes that adopt a formal protocol must specify the protocol in the class declaration and must implement all of the methods specified in the protocol. An informal protocol is, well, less formal. Classes that adopt an informal protocol don’t specify the informal protocol in their declaration and aren’t required to implement all methods specified in the protocol. Informal protocols are often declared as a category of the NSObject. Categories and protocols provide a cleaner separation between the interface and implementation of a class than C++ and address many of the common uses of multiple inheritance.

Objective-C objects have initializer methods which are similar to constructors in C++. Like constructors, an Objective-C class may declare multiple initializers. Unlike constructors, only the initializer for the most-derived class in invoked by the run-time. Unlike constructors, in which the C++ run-time automatically invokes each constructor in the inheritance hierarchy when the object is created, invocation of the initializer is only a convention (e.g., MyClass object = [[ MyClass alloc ] init ];) Therefore, each initializer must explicitly chain to the appropriate initializer of its superclass. Similarly, Objective-C objects have a dealloc method which is similar to a destructor in C++. Like initializer methods, the dealloc method must explicitly chain to the dealloc method of its superclass.

Apple’s The Objective-C Programming Language covers all of this information in great detail. If you are just learning Objective-C and Cocoa, you probably don’t need to read this document. However, if like me, you are interested in understanding how programming languages are designed and implemented, you will find this document beneficial.

2 Responses to “Objective-C for C++ Programmers”

  1. ken Says:

    Useful post!

    > Unlike constructors, only the initializer for the most-derived
    > class in invoked by the run-time.

    I wouldn’t phrase it like that.. the run-time doesn’t have a concept of initializers. Initializers are methods like any other. The only thing that distinguishes them is our convention.

  2. geoff Says:

    Ken, thanks for the feedback. What I had written was misleading at best. I’ve updated the entry accordingly.

Leave a Reply

thoughts yet to be boiled down to their essence