JonHoyle.com Mirror of MacCompanion
http://www.maccompanion.com/macc/archives/September2008/Columns/AccordingtoHoyle37.htm

Resources


Google

macCompanion

Internet


eCost Software Logo

Find any latest Software like Macintosh Software, Apple Mac OS X, Final Cut Studio, Final cut express, Aperture 2 & many more...


Shop at CheckCostUK.

Read reviews & compare prices on Laptop, Apple Laptop, Apple computer, iPod, PDA, MP3 Player & many more....


Evo Networks



Latest Joy of Tech!
Latest Joy of Tech!


3-Rivers Synergy Centre


Visit StepHouse Networks. Broadband DSL for Apple Users




 

Consultants

Developers

Devotees

Downloads

"Foreign" Macs

Forums

Hearsay

Link Lists

Mac 3D

Macazines

Mac Jobs

MUG Shots

News

Radio

Reviews

Think Different

Training

 

According to Hoyle...

 

 

Objective-C for C++ Programmers, Part I


[ Part I | Part II ]


 

September 2008

by Jonathan Hoyle

jonhoyle@mac.com

macCompanion

http://www.jonhoyle.com

 

This month we examine the Objective-C language from a C++ perspective.  Although there are a large number of Objective-C books written for the beginner, these are inappropriate to advanced C++ programmers, as such books tend to belabor elementary concepts.  Advanced Objective-C books are as equally unhelpful, given that they are geared toward those already fluent in the language.  The intention behind the next two articles is to give the competent C++ programmer an understanding of how to translate what he or she already knows, into this (perhaps foreign) dialect.  Unlike languages such as Java, PHP, Ruby and others, Objective-C's strange syntax is so unusual, that it often puts off developers who would otherwise be interested in taking the time to learn the language.

The goal of this two-part study is to offer a "translator" of sorts, defining Objective-C terms and practices, in terms of C++ equivalents (or near equivalents).  We begin this month with Objective-C classes: how they are called, declared and defined.  For each Objective-C syntax introduction we give, C++ code examples will be demonstrated as much a possible.

For those looking for more complete documentation for understanding Objective-C from a C++ perspective, I heartily recommend reading Pierre Chatelier's From C++ to Objective-C.




What Do Those Damn Brackets Mean Anyway?


When C++ programmers see Objective-C code for the first time, they are often taken aback by the bizarre use of square brackets [ ].  In C++, as with C, square brackets are used almost exclusively for array indexing.  But in Objective-C, it has a very different use: it encloses an object's invocation of a method.  In most modern languages, the syntax for method invocation involves the dot operator.  You can think of the C++ call:

    object.method();

as loosely equivalent to Objective-C's:

    [object method];

The former syntax is fairly standardized among most all modern languages.  The latter was borrowed from the object oriented language SmallTalk and is rarely seen outside of Objective-C development.  Note that these calls can be nested, so that the Objective-C line:


    [[[object method1] method2] method3];

is the same as:

    object.method1().method2().method3();

Though such long nestings is generally considered poor style in C++ (not to mention dereferencing function returns), it is common practice in Objective-C, so you better get use to it.

One of the most crucial differences though is that this Objective-C syntax is actually a form of message-passing, not exclusive to method invocation.  In C++, method() must be a member function of the class that object is an instance of.  If not, the line object.method(); would fail to compile.  In Objective-C, method() need not be defined for class of which object is an instance.  There may be any number of potential runtime resolutions to the line [object method]; .  For this reason, Objective-C users need to be less reliant on their compiler catching careless mistakes.  A typo such as [object mehtod]; will not generate the compiler error that object.mehtod() would.




Pass the Function Parameters, Please ...


In the above example, method() took no parameters; so how do you handle methods which do?  This is where things get a little complicated.  Fortunately, passing a single parameter to a method is simple enough though: whereas in C++ the parameter is placed within the function's round brackets:

    object.method(parameter);

in Objective-C, the parameter is separated by the method name by use of the colon:

    [object method:parameter];

With two or more parameters, it can get a bit messy (particularly from a C++ perspective).  Rather than use generic terms, it's better to illustrate with a more specific example.  Let's say you have a classcalled Graph containing a method that obtains the distance from origin for any point in the plane.  The C++ code for such a function might look something like this:

    distance = myGraph.getDistanceFromOriginXandY(xCoord, yCoord);

In C++, additional parameters are separated by commas.  In Objective-C however, the actual function name itself is split up:

    distance = [myGraph getDistanceFromOriginX:xCoord andY:yCoord];

Rather than comma separated, Objective-C method parameters are preceded by tags which are essentially part of the method name itself.  In general, a call of the form:

    [foo bar1:parm1 bar2:parm2 bar3:parm3];

can be thought of as the Objective-C equivalent to the standard C++:

    [foo.bar(parm1, parm2, parm3);

in which the C++ method bar is morphed into the Objective-C method tags bar1, bar2, bar3.




Objective-C Class Declarations


So now you know how to translate Objective-C calling code.  That (believe it or not) is the easy part.  If you are creating your own classes, you must declare and define these functions.  Even if you are not creating them yourself, you may have need to read and understand the implementation of these calls.

Let's begin with class declarations.  Class declarations are what you typically find in C++ header files.  Below is a typically generic C++ class declaration which we will use as our basis for porting to Objective-C:

    class MyClass: public MyBaseClass
    {
        
public:
            
MyClass();
            virtual ~
MyClass();
            int publicMethod();
            void publicMethod(
int myParm);
            
void publicMethod(double myParm);
            
void publicMethod(int myParm1, int myParm2);
            
static short staticMethod();

        
protected:
            
long protectedMethod();
            
double mProtectedMemberData;

        
private:
            
int mPrivateMemberData;
    };


As you can see, MyClass has the usual items that you would expect one to have: a constructor, a destructor, both public and protected methods, protected member data, and even a private member variable.  We see that MyClass is derived from MyBaseClass.  You'll note that the function publicMethod() is overloaded with four prototypes.  Finally, note that we have added a static member function.  This is nothing fancy and could be the outline for many C++ classes you run into.

This is how this same class might be declared in Objective-C:

    @
interface MyClassMyBaseClass
    {
        @
protected:
            
double mProtectedMemberData;

        @
private:
            
int mPrivateMemberData;
    }

    -(
int) publicMethod;
    -(
void) publicMethod:(int)myParm;
    -(
void) publicMethod2:(double)myParm;
    -(
void) publicMethod:(int)myParm1 withOtherParm:(int)myParm2;
    +(
short) staticMethod;
    -(
long) publicMethod3;
    @
end

Okay, getting past the alien looking syntax, let's examine this line by line.  In C++ class declarations are extensions to struct declarations from C, with the added ability to include functions as members.  In Objective-C, a class declaration is quite different, living between the calls @interface and @end.  The @ symbol is used throughout Objective-C to alert the language parser that this is non C-like syntax.

The first line

    @
interface MyClassMyBaseClass

is straightforward enough to understand.  Note though the missing word public from the inheritance.  This is because in Objective-C, class inheritance can only be public.  Furthermore, Objective-C does not support multiple inheritance as C++ does.

Next comes the member data:

    {
        @
protected:
            
double mProtectedMemberData;

        @
private:
            
int mPrivateMemberData;
    }

Again you'll note the similarity with C++, except with the strange @ prefix.  Although it is poor C++ programming style, you may also have public member data, and as you might expect, in Objective-C it would be preceded by the tag @protected.

Unlike in C++ however, Objective-C member functions do not co-mingle with member data.  They are listed separately as follows:

    -(int) publicMethod;
    -(
void) publicMethod:(int)myParm;
    -(
void) publicMethod2:(double)myParm;
    -(
void) publicMethod:(int)myParm1 withOtherParm:(int)myParm2;

The first thing you'll note is that member function declarations begin with a - (dash) followed by the return type in parentheses, followed in turn by the function name.  If there are function parameters, they are listed colon-separated with (once again) the type in parentheses followed by the name.

You'll notice is that the third C++ prototypes for publicMethod() has been given a different name.  This is because Objective-C, like C, is limited to requiring each function name to be unique.  The first method's name (as you would expect) is simply "-publicMethod".  The second one's name is "-publicMethod:", that is, with a colon suffix indicating a single parameter.  To avoid a name conflict, the third prototype was renamed, so that its official name would be "-publicMethod2:" rather than "-publicMethod:".  The final prototype fails to conflict since its official name is "-publicMethod:withOtherParm:".

Static methods are declared similarly to non-static methods, except with a + prefix:

    +(short) staticMethod;

Finally, we come to the protected C++ member protectedMethod().  Unfortunately, all Objective C member functions are public.  No protected or private functions are allowed.  For this reason, we changed the name of this function:

    -(long) publicMethod3;

And now we reach the end of the declaration with @end.

You'll notice that we have intentionally skipped the constructor and destructor in our port of MyClass.  In Objective-C, these concepts are replaced by initialization and allocation and will be the focus of next month's column.  For now, let us pretend they do not exist and we will return to them next time, I promise.




Objective-C Class Definitions


Once a class is declared in a header file, it must then be defined in a source file.  In C++, this is typically a file using a .cpp extension (alternatively .cp or .cc).  In the example of MyClass, we would usually find the class declaration in a file called MyClass.h, the definition in MyClass.cpp, and near the top of the latter file, we would expect to find the line:

    #include "MyClass.h"

Each method of MyClass would be defined separately within MyClass.cpp, examples of which include:

    
int MyClass::publicMethod()
    {
        
... // Actual code
    }

    
void MyClass::publicMethod(int myParm1, int myParm2)
    {
        
... // Actual code
    }

In C++ , methods are defined just like standard C functions, with the exception that the class name and double colon prefixes the method name.  MyClass:: places the method name publicMethod() within the scope of the class MyClass.  This form of scope resolution is used without C++, not just for classes but for namespaces as well.

By now, it should comes as no surprise that Objective-C methods are not defined anything like C++ methods, and that the strange @ symbol will be key.  Although Objective-C header files retain the .h suffix, Objective-C source files typically use a .m suffix.  The inclusion directive is also different, so near the top of MyClass.m, we would find:

    #import "MyClass.h"

The main difference between the Objective-C #import directive and the standard C #include is that the former suppresses multiple inclusions.  To achieve this same affect, C programmers have often use macros to avoid multiple inclusion, as follows:

    // MyClass.h header file
    #
ifndef MYCLASS_H
    #
define MYCLASS_H
        ... // Class declaration
    #
endif // MYCLASS_H

Objective-C's #import makes this redundant.

Analogous to method declarations, Objective-C method definitions must be enclosed within an @implementation scope.  The definitions themselves follow the syntax of the declaration, as the following example shows:

    @
implementation MyClass

    -(
int) publicMethod
    {
        
... // Actual code
    }

    -(
void) publicMethod: (int) myParm1: (int) myParm2
    {
        ... // Actual code
    }

    // Remaining method definitions
    ...
    @
end




Conclusions So Far ...


This month we have learned how to define, declare and call Objective-C class methods.  Yes, Objective-C is very different syntactically.  And indeed, it is sometimes a little hard on the eyes.  But much of this is due to its legacy and age.  Modern languages have come about during a time when the dot syntax has become standardized.  In the 1980's when Objective-C was being developed, C++ was also in its infancy, so there was no way of knowing which convention would win out.  The Objective-C 2.0 standard (2007) has made some small steps to remedy this problem, but there is still a long way to go.  Like learning to speak a foreign language, it takes time and effort to develop fluency.




Coming Up Next Month: More of our investigation of Objective-C from a C++ perspective.  See you in 30!


[ Part I | Part II ]


See a list of all the According to Hoyle columns 

 

http://www.maccompanion.com/macc/archives/September2008/Columns/AccordingtoHoyle37.htm