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.
 
AAPL
$501.11
Apple Inc.
+2.43
MSFT
$34.64
Microsoft Corpora
+0.15
GOOG
$898.03
Google Inc.
+16.02

MacTech Search:
Community Search:

Software Updates via MacUpdate

CrossOver 12.5.1 - Run Windows apps on y...
CrossOver can get your Windows productivity applications and PC games up and running on your Mac quickly and easily. CrossOver runs the Windows software that you need on Mac at home, in the office,... Read more
Paperless 2.3.1 - Digital documents mana...
Paperless is a digital documents manager. Remember when everyone talked about how we would soon be a paperless society? Now it seems like we use paper more than ever. Let's face it - we need and we... Read more
Apple HP Printer Drivers 2.16.1 - For OS...
Apple HP Printer Drivers includes the latest HP printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.16.1: This... Read more
Yep 3.5.1 - Organize and manage all your...
Yep is a document organization and management tool. Like iTunes for music or iPhoto for photos, Yep lets you search and view your documents in a comfortable interface, while offering the ability to... Read more
Apple Canon Laser Printer Drivers 2.11 -...
Apple Canon Laser Printer Drivers is the latest Canon Laser printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.11... Read more
Apple Java for Mac OS X 10.6 Update 17 -...
Apple Java for Mac OS X 10.6 delivers improved security, reliability, and compatibility by updating Java SE 6.Version Update 17: Java for Mac OS X 10.6 Update 17 delivers improved security,... Read more
Arq 3.3 - Online backup (requires Amazon...
Arq is online backup for the Mac using Amazon S3 and Amazon Glacier. It backs-up and faithfully restores all the special metadata of Mac files that other products don't, including resource forks,... Read more
Apple Java 2013-005 - For OS X 10.7 and...
Apple Java for OS X 2013-005 delivers improved security, reliability, and compatibility by updating Java SE 6 to 1.6.0_65. On systems that have not already installed Java for OS X 2012-006, this... Read more
DEVONthink Pro 2.7 - Knowledge base, inf...
Save 10% with our exclusive coupon code: MACUPDATE10 DEVONthink Pro is your essential assistant for today's world, where almost everything is digital. From shopping receipts to important research... Read more
VirtualBox 4.3.0 - x86 virtualization so...
VirtualBox is a family of powerful x86 virtualization products for enterprise as well as home use. Not only is VirtualBox an extremely feature rich, high performance product for enterprise customers... Read more

Briquid Gets Updated with New Undo Butto...
Briquid Gets Updated with New Undo Button, Achievements, and Leaderboards, on Sale for $0.99 Posted by Andrew Stevens on October 16th, 2013 [ | Read more »
Halloween – iLovecraft Brings Frightenin...
Halloween – iLovecraft Brings Frightening Stories From Author H.P. | Read more »
The Blockheads Creator David Frampton Gi...
The Blockheads Creator David Frampton Gives a Postmortem on the Creation Process of the Game Posted by Andrew Stevens on October 16th, 2013 [ permalink ] Hey, a | Read more »
Sorcery! Enhances the Gameplay in Latest...
Sorcery! | Read more »
It Came From Australia: Tiny Death Star
NimbleBit and Disney have teamed up to make Star Wars: Tiny Death Star, a Star Wars take on Tiny Tower. Right now, the game is in testing in Australia (you will never find a more wretched hive of scum and villainy) but we were able to sneak past... | Read more »
FIST OF AWESOME Review
FIST OF AWESOME Review By Rob Rich on October 16th, 2013 Our Rating: :: TALK TO THE FISTUniversal App - Designed for iPhone and iPad A totalitarian society of bears is only the tip of the iceberg in this throwback brawler.   | Read more »
PROVERBidioms Paints English Sayings in...
PROVERBidioms Paints English Sayings in a Picture for Users to Find Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
OmniFocus 2 for iPhone Review
OmniFocus 2 for iPhone Review By Carter Dotson on October 16th, 2013 Our Rating: :: OMNIPOTENTiPhone App - Designed for the iPhone, compatible with the iPad OmniFocus 2 for iPhone is a task management app for people who absolutely... | Read more »
Ingress – Google’s Augmented-Reality Gam...
Ingress – Google’s Augmented-Reality Game to Make its Way to iOS Next Year Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
CSR Classics is Full of Ridiculously Pre...
CSR Classics is Full of Ridiculously Pretty Classic Automobiles Posted by Rob Rich on October 16th, 2013 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Apple Store Canada offers refurbished 11-inch...
 The Apple Store Canada has Apple Certified Refurbished 2013 11″ MacBook Airs available starting at CDN$ 849. Save up to $180 off the cost of new models. An Apple one-year warranty is included with... Read more
Updated MacBook Price Trackers
We’ve updated our MacBook Price Trackers with the latest information on prices, bundles, and availability on MacBook Airs, MacBook Pros, and the MacBook Pros with Retina Displays from Apple’s... Read more
13-inch Retina MacBook Pros on sale for up to...
B&H Photo has the 13″ 2.5GHz Retina MacBook Pro on sale for $1399 including free shipping. Their price is $100 off MSRP. They have the 13″ 2.6GHz Retina MacBook Pro on sale for $1580 which is $... Read more
AppleCare Protection Plans on sale for up to...
B&H Photo has 3-Year AppleCare Warranties on sale for up to $105 off MSRP including free shipping plus NY sales tax only: - Mac Laptops 15″ and Above: $244 $105 off MSRP - Mac Laptops 13″ and... Read more
Apple’s 64-bit A7 Processor: One Step Closer...
PC Pro’s Darien Graham-Smith reported that Canonical founder and Ubuntu Linux creator Mark Shuttleworth believes Apple intends to follow Ubuntu’s lead and merge its desktop and mobile operating... Read more
MacBook Pro First, Followed By iPad At The En...
French site Info MacG’s Florian Innocente says he has received availability dates and order of arrival for the next MacBook Pro and the iPad from the same contact who had warned hom of the arrival of... Read more
Chart: iPad Value Decline From NextWorth
With every announcement of a new Apple device, serial upgraders begin selling off their previous models – driving down the resale value. So, with the Oct. 22 Apple announcement date approaching,... Read more
SOASTA Survey: What App Do You Check First in...
SOASTA Inc., the leader in cloud and mobile testing announced the results of its recent survey showing which mobile apps are popular with smartphone owners in major American markets. SOASTA’s survey... Read more
Apple, Samsung Reportedly Both Developing 12-...
Digitimes’ Aaron Lee and Joseph Tsai report that Apple and Samsung Electronics are said to both be planning to release 12-inch tablets, and that Apple is currently cooperating with Quanta Computer on... Read more
Apple’s 2011 MacBook Pro Lineup Suffering Fro...
Appleinsider’s Shane Cole says that owners of early-2011 15-inch and 17-inch MacBook Pros are reporting issues with those models’ discrete AMD graphics processors, which in some cases results in the... Read more

Jobs Board

*Apple* Retail - Manager - Apple (United Sta...
Job SummaryKeeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, youre a master of them all. In the stores fast-paced, dynamic Read more
*Apple* Support / *Apple* Technician / Mac...
Apple Support / Apple Technician / Mac Support / Mac Set up / Mac TechnicianMac Set up and Apple Support technicianThe person we are looking for will have worked Read more
Senior Mac / *Apple* Systems Engineer - 318...
318 Inc, a top provider of Apple solutions is seeking a new Senior Apple Systems Engineer to be based out of our Santa Monica, California location. We are a Read more
*Apple* Retail - Manager - Apple Inc. (Unite...
Job Summary Keeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you’re a master of them all. In the store’s fast-paced, Read more
*Apple* Solutions Consultant - Apple (United...
**Job Summary** Apple Solutions Consultant (ASC) - Retail Representatives Apple Solutions Consultants are trained by Apple on selling Apple -branded products Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.