TweetFollow Us on Twitter

June 91 - The Soup Kitchen - C++ing with MacApp

The Soup Kitchen - C++ing with MacApp

Eric M. Berdahl

ETO #4 will soon arrive on our doorsteps, if you believe the current APDA release schedule. An early version of MacApp 3.0 is promised on that CD-the so-called "C++ MacApp." This means, among other things, that many developers will need to be able to read C++ code, and perhaps even need to patch it. This issue, I'll look at some common MacApp constructs and show how C++ handles them.

ALLOCATION AND DEALLOCATION

One of the basic concepts of object programming is creating objects and disposing of them. These topics, in turn, break down into two separate issues: allocation and deallocation, and construction and destruction. MacApp supports all these areas, sometimes by convention, and other times by collaboration with the development environment.

Object Pascal extends Pascal's allocation and deallocation routines, NEW and DISPOSE, to work on object variables. Thus, the following may be written in Pascal:

VAR
anObject: TObject;
BEGIN
    NEW(anObject);
    DISPOSE(anObject);
END;

The Pascal compiler translates calls to NEW with an object argument into calls to a "magic" subroutine %_OBNEW, which then calls routines to allocate storage. In C++, classes that inherit from PascalObject also get this behavior. Thus, the equivalent C++ code looks like this:

{  TObject*    anObject;
    anObject = new TObject;
    delete anObject;
}

So, judging from this section of code, the new and delete functions are C++ analogs of NEW and DISPOSE. However, you have to tell new to create a TObject, whereas NEW simply knows what to create. When the Pascal compiler sees a call to the NEW procedure, it looks at the argument and decides what type it is. If the variable is an object, it calls the aforementioned %_OBNEW procedure, passing it information about the class of the NEW argument.

C++ takes a slightly different approach. The C++ new is told what type to create- TObject in this example-and calls %_OBNEW with the information about the class indicated by the programmer. The new function then returns a reference to the indicated class. This means that you can assign the result of new to a variable of that class or, alternatively, to a variable of a parent class. Thus, the code in the DoMenuCommand in C++ listing is perfectly legal. The equivalent Pascal code is shown in the DoMenuCommand in Pascal listing. And, of course, the C++ code may also be written using explicit variables for TFooCommand and TBarCommand, if you prefer.

In contrast, delete works on Pascal objects just as the DISPOSE routine, although in the MacApp world the Free method is always used instead.

CONSTRUCTION AND DESTRUCTION

Walking hand-in-hand with allocation and deallocation are the ideas of construction and destruction. Construction is the concept that an object should be placed into a known state as soon as it's created. Destruction is the concept of disposing of "owned" objects or performing other clean up necessary when an object ceases to exist. C++ provides a language mechanism that guarantees that these things occur when and where appropriate. Thus, there is a syntax for defining a constructor for a class that is called when an instance begins its existence, and a destructor that is called when an instance ceases to exist.

The implementation of these features in the language is very robust; they ensure that the parent class is completely constructed before the child class and that the child is destructed before the parent.

Constructors and destructors are common in pure C++ code; however, you should never write constructors for classes inheriting from PascalObject (i.e. classes meant to be link-compatible with Object Pascal). In the MacApp world, initialization methods are always used instead. MacApp 2.0.x "IMyObject" initialization methods have the general form:

BEGIN
    SetMyInstanceVariablesToSafeValues;
    SELF.IMyParentObject;
    InitializeMyInstanceVariablesToRealValues;
END;

The SetMyInstanceVariablesToSafeValues part acts like a constructor. The purpose is to place the object into a state such that Free is safe to call, if necessary. This means that pointers are set to nil, and so on. Some time ago, there was some discussion on MacApp.Tech$ contending that the TObject method Initialize should automagically be called when an object is allocated; this would add a more automatic construction behavior to MacApp.

A sort of automatic construction behavior is present in the MacApp 3.0 world. MacApp 3.0 IMyObject methods simply move the constructor portion shown above into an Initialize method. Initialize is invoked from IObject, and is implemented for all the standard MacApp classes. All subclasses define overrides of Initialize which first call the inherited version, then initialize local instance variables to safe values. Thus, the only time it is dangerous to Free an object is between allocation (i.e. new) and initialization (i.e. IMyObject). In practice this is not a problem if you follow the convention that Initialize must not fail. Following this convention should not be difficult since Initialize should only set instance variables to default values, and nothing more.

Destruction is handled by Free methods. By convention, a class' Free method does all necessary clean-up before invoking the parent class' version of Free. This does by convention what C++ destructors do automagically. So, if C++ constructors and destructors are so great, why not use them in MacApp? Because that would result in code that isn't link-compatible with Object Pascal. Pascal won't call C++'s constructors or destructors, so relying on them could lead to disastrous consequences.

A SIMPLE ROUTINE

The GetQDExtent in C++ listing shows an actual method taken from the MacApp 3.0 source code. I'll refer to it several times to denote various constructs used in C++ coding. The GetQDExtent in Pascal listing shows the equivalent Pascal code.

One of the first things to notice is that the C++ version of GetQDExtent uses the pascal void construct. Remember from the introduction to C++ interfaces in the last issue that pascal <Something> denotes a Pascal FUNCTION with return type <Something>, and that pascal void denotes a Pascal PROCEDURE.

Next, notice that "TView::GetQDExtent" correlates with "TView.GetQDExtent" in the Pascal code. The "::" is called the scope resolution operator. It casts a fair amount of magic in purist C++ code, but only has two common uses in the MacApp world. Method declaration as seen here is one place where "::" is used; the other will be revealed shortly.

Further comparison shows that the C++ keyword this is equivalent to the Pascal keyword SELF. Just as SELF is a Pascal meta-variable that indicates the particular instance a method is manipulating, this is the C++ meta-variable. All magic provided by Pascal in regards to SELF carries over to this in C++.

ACCESSING CLASS FEATURES

Method invocations and instance variable access are produced with the arrow operator, "->". Like its Pascal cousin, the dot operator, ".", the C++ arrow operator works on an object to call a method or access an instance variable. So, this->GetExtent(vr) is the C++ equivalent of the Pascal SELF.GetExtent(vr).

Similarly, you use anObject->fAnInstanceVar in a C++ method to do something with the instance variable fAnInstanceVar or the anObject object. Although this- >fAnInstanceVar is syntactically correct, you can just write fAnInstanceVar. The this-> is implied in C++ methods just as SELF. is implied in Pascal methods, and the convention of beginning field names with lowercase f makes it clear that fAnInstanceVar is an instance variable. For clarity, however, most style guides recommend explicitly using this->MethodCall() in C++ just as one would use SELF.MethodCall in Pascal.

There is another form of method invocation common to MacApp programming: calling the parent class' version of a method. Object Pascal provides the INHERITED keyword for this purpose. For a discussion of this topic, see James Plamondon's article "TAspectPicture-A problem to sleep on" in the April '91 issue of FrameWorks.

In C++, you can call the parent class' version of a method in two different ways. Traditional C++ programmers use the construct TParentClass::MethodCall(arg). In this form, MethodCall names the method you want to invoke, and TParentClass is the class that implements the version of MethodCall you want to use (passing arg as an argument). This construct bypasses the method dispatcher and explicitly calls the indicated implementation of MethodCall. This construct allows you to skip up the inheritance chain directly to any class that implements the method you name-parent class, grandparent class, etc-without executing implementations of that method that are made by intervening classes in the inheritance chain.

Usually you don't want to bypass the method dispatcher in this fashion. Instead, you want to dispatch your method starting with the parent class. Due to what I feel is a deficit in C++, no shorthand exists for calling an inherited method in this manner; however, MPW C++ provides an extension to do just that based on Pascal's INHERITED keyword. In MPW C++ you can write inherited::Draw(aRect) just as you might write INHERITED Draw(aRect) in Pascal.

VARIABLE DECLARATIONS

One major difference between C++ and Pascal methods is their local variable declarations. Pascal provides an explicit VAR area for all variable declarations. In C++, a variable declaration (e.g. "char aChar;") is a full-fledged statement; thus, it can appear anywhere a statement may appear in code.

Arbitrary placement of local variable declaractions is another feature of the language that may be important if you do pure, non-MacApp C++ coding; however, as a matter of style, many Mac C++ programmers declare all local variables in a cluster at the beginning of a method. A common variant on the simple declaration is the addition of an initial value to the declaration. Thus, "char aChar = 'a';" not only declares a variable named aChar of type char, it also immediately sets it to be the character 'a'.

REFERENCE VARIABLES

I'm going to take a break from dissecting this method to discuss C++ reference variables. These are possibly the most difficult concept of C++ to grasp, because they have no correlation in Pascal. A reference variable looks like this:
short       anInteger;
short&      someInteger = anInteger;

Here, anInteger is an integer, and someInteger is a reference to an integer variable (anInteger in this case).

References can be thought of as pointers that must always point to something. Another popular analogy is that references are aliases to another variable. Since references must always refer to something, when a reference is declared, it must be initialized with a valid variable, as above. Using the declarations above, someInteger may be substituted for anInteger everywhere. Literally, if you do something to someInteger, you're really doing it to anInteger. You won't be using references in MacApp programming, except for…

PARAMETER PASSING

The rules for Pascal parameter passing are something C++ programmers recite in their sleep. What the Pascal compiler does for you, the C++ interface must be designed to emulate. The rules are very simple:
  • All VAR parameters are passed by pushing a pointer to the variable on the stack.
  • Non-VAR parameters that are 4 bytes or smaller are passed by pushing a copy of the variable directly on the stack.
  • Non-VAR parameters that are larger than 4 bytes are passed by pushing a pointer to the variable on the stack.

So, if you have a routine like FrameRect, "PROCEDURE FrameRect(aRect: Rect)", you could declare it in C++ as "pascal void FrameRect(Rect* aRect)". Further, since aRect is a value parameter, you can denote that it won't be altered by changing the declaration to "pascal void FrameRect(const Rect* aRect)". This is perfectly legal, but has a minor pitfall. Since all C++ knows that FrameRect wants a pointer passed, it is syntactically legitimate to call "FrameRect(nil)". Guess what happens when you do that? What you really want the compiler to do is pass FrameRect a pointer to a Rect and ensure that the pointer in not nil-you want a reference to a Rect. To do this, the declaration then becomes "pascal void FrameRect(const Rect& aRect)", which is just the way it's defined in the C++ toolbox interfaces distributed with MacApp 3.0.

A BIT OF HISTORICAL IRONY

If you've been reading C++ interface files provided with MacApp 2.0.x and MPW, you may be more than a bit confused. These products don't work with reference variables as I've described above. Instead, they use the intermediate "pascal void FrameRect(const Rect* aRect)" form. However, MacApp 3.0 ships with C++ interface files that use reference variables. The hope is that the toolbox interfaces will be merged with the MPW product at some time in the near future. In any case, MacApp 3.0 C++ coders will use them.

By the way, this change absolutely guarantees that any existing C++ MacApp 2.0 code will fail to compile under MacApp 3.0. Because C++ programmers have been passing pointers to routines that now expect the real McCoy, all that code will need to be revamped.

A side effect of using this convention of passing parameters is that the MacApp C++ sources have a distinctly Pascal-like flavor to them, as does MacApp 3.0 C++ code in general. That is, I don't need to know whether a method can change a variable or not (i.e. is it VAR?). I write my code the same way in either case; just write the name of the variable and let the compiler worry about whether to push a pointer or a copy of the variable. Pascal programmers should feel very comfortable with this situation since this is exactly the convention used by the Pascal language.

NEXT TIME…

…I'll be looking at some real magic of Pascal and C++, and some of MacApp 3.0's new features. Each language provides interesting and useful constructs, especially if you happen to be programming in that language. I'm looking for those wonderful "How do you do <feature of one language> in <the other language>?" and "Isn't there a better way?" questions. As always, questions, comments, and other feedback are encouraged at AppleLink: BERDAHL.
 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Can PokeMatch help you find love with Po...
The unofficial Pokemon GO companion app space has exploded almost as fast as the game itself over the last few weeks. Aspiring app developers, many of them working solo, have given us apps that locate Pokemon, keep track of the server status, and... | Read more »
How to get started with Prisma
If there's one thing people like to do more than taking pictures with their smartphones, it's tinkering with those photos in some way. Numerous apps have sprung up over the last several years that allow you to use filters and special effects to... | Read more »
6 Pokemon GO updates you can expect, acc...
Pokemon GO had a scheduled appearance at this year's San Diego Comic-Con for a while, but it was only relatively close to the show that it was upgraded to a spot in Hall H. That's the biggest venue at SDCC, one usually reserved for the largest... | Read more »
How to evolve Eevee in Pokemon GO
By now, almost everyone should be hip to how to evolve Pokemon in Pokemon GO (and if not, there's a guide for that). Just gather enough candy of the appropriate type, feed them all to the Pokemon, and evolution happens. It's a miracle that would... | Read more »
CSR Racing 2: Guide to all game modes
It might not seem like there are all that many ways to go fast in a straight line, but CSR Racing 2 begs to differ. [Read more] | Read more »
Bulb Boy (Games)
Bulb Boy 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Multi-award winning 2D point & click horror adventure about a boy with a glowing head. | Read more »
5 top free emoji keyboard apps
If we're not at peak emoji yet as a society, it feels like we definitely should be. The emoji concept has gone far beyond what anyone in Japan could have envisioned when the people there unleashed it on an unsuspecting world, but the West has... | Read more »
How to unlock more characters in Disney...
One of the big charms of Disney Emoji Blitz is seeing a wide variety of beloved Disney and Pixar characters transformed into smiling emojis. Even someone like the sneaky Randall from Monsters Inc., who probably never cracked a smile on film, is... | Read more »
Cubway (Games)
Cubway 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Cubway is a journey with an abstract story of lifecycle of rebirth, called Samsara. Guide the cube through the long way full of dangers... | Read more »
Colorcube (Games)
Colorcube 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Turn pieces and blend colours in this minimal yet visually stunning puzzler.Over 200 handcrafted and challenging levels. Features... | Read more »

Price Scanner via MacPrices.net

Apple’s 2016 Back to School promotion: Free B...
Purchase a new Mac or iPad using Apple’s Education Store and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free, and... Read more
Apple refurbished iPad Air 2s available start...
Apple has Certified Refurbished iPad Air 2 available starting at $339. Apple’s one-year warranty is included with each model, and shipping is free: - 128GB Wi-Fi iPad Air 2: $499 - 64GB Wi-Fi iPad... Read more
13-inch 2.5GHz MacBook Pro available for $964...
Overstock has the 13″ 2.5GHz MacBook Pro available for $964.21 including free shipping. Their price is $135 off MSRP. Read more
External Keyboard Innovations For iPad Pro (1...
I’m an input device aficionado. With non-touchscreen computers, which includes all Macs, the keyboard and mouse or trackpad are the tactile points of interface between user and machine, and the... Read more
GSK Rheumatoid Arthritis Study Leverages iPho...
Global healthcare products company GlaxoSmithKline (GSK) says that since 2014 they have begun transforming the way they conduct research, by leveraging state-of-the-art digital technologies — a... Read more
Clearance 12-inch Retina MacBooks, Apple refu...
Apple has Certified Refurbished 2015 12″ Retina MacBooks available starting at $929. Apple will include a standard one-year warranty with each MacBook, and shipping is free. The following... Read more
13-inch Retina MacBook Pros on sale for up to...
B&H Photo has 13″ Retina MacBook Pros on sale for up to $150 off MSRP. Shipping is free, and B&H charges NY tax only: - 13″ 2.7GHz/128GB Retina MacBook Pro: $1199 $100 off MSRP - 13″ 2.7GHz/... Read more
13-inch 1.6GHz/128GB MacBook Air on sale for...
Amazon has the 13″ 1.6GHz/128GB MacBook Air on sale for $200 off MSRP for a limited time. Shipping is free: - 13″ 1.6GHz/128GB MacBook Air (sku MMGF2LL/A): $799.99 $200 off MSRP Their price is the... Read more
13-inch 1.6GHz/256GB MacBook Air on sale for...
Amazon has the 13″ 1.6GHz/256GB MacBook Air on sale for $200 off MSRP for a limited time. Shipping is free: - 13″ 1.6GHz/256GB MacBook Air (sku MMGG2LL/A): $999.99 $200 off MSRP Their price is the... Read more
Free iOS Business App notably* Helps Service...
PayStudio Inc. has introduced their new business app notably* 1.0, developed for iPhone and iPod touch. notably* was specifically developed to help service and trade professionals go digital and... Read more

Jobs Board

*Apple* Retail - Multiple Positions, Willow...
Job Description:SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Evangelist - JAMF Software (United S...
The Apple Evangelist is responsible for building and cultivating strategic relationships with Apple 's small and mid-market business development field teams. This Read more
*Apple* Solutions Consultant - APPLE (United...
Job Summary As an Apple Solutions Consultant, you'll be the link between our future customers and our products. You'll showcase your entrepreneurial spirit as you Read more
*Apple* Professional Learning Specialist - A...
Job Summary The Apple Professional Learning Specialist is a full-time position for one year with Apple in the Phoenix, AZ area. This position requires a high Read more
*Apple* Picker - Apple Hill Orchard (United...
Apple Hill Orchard, Co. Rte. 21,Whitehall, NY 9/7/16-10/228/16. Pick fresh market or processing apples Productivity of 60 boxes and 80 boxes processing fruit per Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.