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
$119.00
Apple Inc.
+1.40
MSFT
$47.75
Microsoft Corpora
+0.28
GOOG
$540.37
Google Inc.
-0.71

MacTech Search:
Community Search:

Software Updates via MacUpdate

HoudahSpot 3.9.6 - Advanced file search...
HoudahSpot is a powerful file search tool built upon MacOS X Spotlight. Spotlight unleashed Create detailed queries to locate the exact file you need Narrow down searches. Zero in on files Save... Read more
RapidWeaver 6.0.3 - Create template-base...
RapidWeaver is a next-generation Web design application to help you easily create professional-looking Web sites in minutes. No knowledge of complex code is required, RapidWeaver will take care of... Read more
iPhoto Library Manager 4.1.10 - Manage m...
iPhoto Library Manager lets you organize your photos into multiple iPhoto libraries. Separate your high school and college photos from your latest summer vacation pictures. Or keep some photo... Read more
iExplorer 3.5.1.9 - View and transfer al...
iExplorer is an iPhone browser for Mac lets you view the files on your iOS device. By using a drag and drop interface, you can quickly copy files and folders between your Mac and your iPhone or... Read more
MacUpdate Desktop 6.0.3 - Discover and i...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
SteerMouse 4.2.2 - Powerful third-party...
SteerMouse is an advanced driver for USB and Bluetooth mice. It also supports Apple Mighty Mouse very well. SteerMouse can assign various functions to buttons that Apple's software does not allow,... Read more
iMazing 1.1 - Complete iOS device manage...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
PopChar X 7.0 - Floating window shows av...
PopChar X helps you get the most out of your font collection. With its crystal-clear interface, PopChar X provides a frustration-free way to access any font's special characters. Expanded... Read more
Carbon Copy Cloner 4.0.3 - Easy-to-use b...
Carbon Copy Cloner backups are better than ordinary backups. Suppose the unthinkable happens while you're under deadline to finish a project: your Mac is unresponsive and all you hear is an ominous,... Read more
ForeverSave 2.1.3 - Universal auto-save...
ForeverSave auto-saves all documents you're working on while simultaneously doing backup versioning in the background. Lost data can be quickly restored at any time. Losing data, caused by... Read more

Latest Forum Discussions

See All

Bounce On Back (Games)
Bounce On Back 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: | Read more »
Make Way for Fat Chicken, from the Maker...
Make Way for Fat Chicken, from the Makers of Scrap Squad Posted by Jessica Fisher on November 26th, 2014 [ permalink ] Relevant Games has announced they will be releasing their reverse tower defense game, | Read more »
Tripnary Review
Tripnary Review By Jennifer Allen on November 26th, 2014 Our Rating: :: TRAVEL BUCKET LISTiPhone App - Designed for the iPhone, compatible with the iPad Want to create a travel bucket list? Tripnary is a fun way to do exactly that... | Read more »
Ossian Studios’ RPG, The Shadow Sun, is...
Ossian Studios’ RPG, The Shadow Sun, is Now Available for $4.99 Posted by Jessica Fisher on November 26th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Mmmm, Tasty – Having the Angry Birds for...
The very first Angry Birds debuted on iOS back in 2009. When you sit back and tally up the number of Angry Birds games out there and the impact they’ve had on pop culture as a whole, you just need to ask yourself: “How would the birds taste... | Read more »
Rescue Quest Review
Rescue Quest Review By Jennifer Allen on November 26th, 2014 Our Rating: :: PATH BASED MATCH-3Universal App - Designed for iPhone and iPad Guide a wizard to safety by matching gems. Rescue Quest might not be an entirely original... | Read more »
You Can Play the Final Chapter of Lone W...
You Can Play the Final Chapter of Lone Wolf: Dawn Over V’taag Right Now Posted by Jessica Fisher on November 26th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Swords of Anima (Games)
Swords of Anima 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: A new tactical turn-based RPG experience. Command the Savior Rex Squad in an epic journey of courage and deception. Can you... | Read more »
Audio Defence: Zombie Arena
Audio Defence: Zombie Arena By Lee Hamlet on November 26th, 2014 Our Rating: :: DRAGS ITS FEETUniversal App - Designed for iPhone and iPad From the makers of Papa Sangre comes a defense game that forces players to listen carefully... | Read more »
Tales from the Borderland​s Will be Comi...
Tales from the Borderland​s Will be Coming to iOS by the End of the Year Posted by Jessica Fisher on November 26th, 2014 [ permalink ] Telltale Games has announced | Read more »

Price Scanner via MacPrices.net

2014 1.4GHz Mac mini on sale for $449, save $...
 B&H Photo has the new 1.4GHz Mac mini on sale for $449.99 including free shipping plus NY tax only. Their price is $50 off MSRP, and it’s the lowest price available for this new model. Adorama... Read more
Early Black Friday pricing on 27-inch 5K iMac...
 B&H Photo continues to offer Black Friday sale prices on the 27″ 3.5GHz 5K iMac, in stock today and on sale for $2299 including free shipping plus NY sales tax only. Their price is $200 off MSRP... Read more
Early Black Friday sale prices on iPad Air 2,...
 MacMall is discounting iPad Air 2s by up to $75 off MSRP as part of their Black Friday sale. Shipping is free: - 16GB iPad Air WiFi: $459 $40 off - 64GB iPad Air WiFi: $559 $40 off - 128GB iPad Air... Read more
Early Black Friday MacBook Air sale prices, $...
 MacMall has posted early Black Friday MacBook Air sale prices. Save $101 on all models for a limited time: - 11″ 1.4GHz/128GB MacBook Air: $798 - 11″ 1.4GHz/256GB MacBook Air: $998 - 13″ 1.4GHz/... Read more
Why iPhone 6 Tablet/Laptop Cannibalization Is...
247wallst.com blogger Douglas A. McIntyre noted last week that according to research posted on the Applovin blog site the iPhone 6 is outselling the iPhone 6 Plus by a wide margin . Hardly a surprise... Read more
Worldwide Tablet Growth Expected to Slow to 7...
The global tablet market is expected to record massive deceleration in 2014 with year-over-year growth slowing to 7.2%, down from 52.5% in 2013, according to a new forecast from International Data... Read more
Touchscreen Glove Company Announces New Produ...
Surrey, United Kingdom based TouchAbility specializes in design and manufacture of a wide variety of products compatible with touchscreen devices including smartphones, tablets and computers. Their... Read more
OtterBox Alpha Glass Screen Protectors for iP...
To complement the bigger, sharper displays on the latest Apple devices, OtterBox has introduced Alpha Glass screen protectors to the iPhone 6 and iPhone 6 Plus. The fortified glass screen protectors... Read more
Early Black Friday Mac Pro sale, 6-Core 3.5GH...
 B&H Photo has the 6-Core 3.5GHz Mac Pro on sale today for $3499 including free shipping plus NY sales tax. Their price is $500 off MSRP, and it’s the lowest price available for this model from... Read more
Early Black Friday sale price: 15-inch 2.2GHz...
 B&H Photo has the 2014 15″ 2.2GHz Retina MacBook Pro on sale today for $1699.99. Shipping is free, and B&H charges NY sales tax only. Their price is $300 off MSRP, equalling Best Buy’s price... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.