October 1997

Property macros

by Sam Azer

A moderately complicated class definition can begin to look rather messy as you add properties. For example, in order to define a published integer property called Count that displays as multiples of 123 and has no default value, you’d have to enter code like the following:

private:int fCount;
private:int __fastcall GetCount(void) 
{ return fCount * 123; }; 
void __fastcall SetCount(int v) 
{ fCount = v/123; }; 
__published: __property int Count2 = 
{ read=GetCount, write=SetCount, nodefault };
All this code for a single property! You might have a dozen or more properties in a medium-sized component, creating an unruly mess that’s difficult to edit. To make such code look better, the class member definitions often appear together in a group, with the get/set functions following and the properties at the end--but then each property is divided into three separate sections of the class definition.

Fortunately, there’s a ready solution to our dilemma. Because the structure of the property-related code is so consistent, the C preprocessor can automate most of the grunt work. Included with this month’s sample files in the oct97.zip file is a header called Prop.H, which contains the required macros. You can write all the code from the previous example using the following macro call:

PROP_PUBLISHED_LGS(int,Count,nodefault,
{ return fCount * 123; },
{ fCount = v/123; } );
The main advantage of using the macros is that everything related to each property is brought together in one section. Also, the code is easier to read and maintain, thereby reducing the chance of errors.

The macros are really quite simple, but they’re not fun to read. The previous example is implemented in a way similar to the following:

#define PROP_PUBLISHED_LGS(typ,nam,str,g,s) \
private: typ f##nam; \
private: typ __fastcall Get##nam(void) g; \
void __fastcall Set##nam(typ v) s; \
published: __property typ nam = \
{ read=Get##nam, write=Set##nam, str }

The documentation at the beginning of Prop.H provides general information on the other available macros.

If you’re getting into C++ from Delphi, you may not be familiar with the C preprocessor. To help you see how a macro expands, C++Builder comes with its own preprocessor: CPP32. To try it, copy the Prop.H file to P.CPP (the example code won’t compile without a CPP extension) and run the command line

cpp32 -P- -DPROPHTEST p.cpp
Doing so will leave you with a file called P.I, which you won’t be able to open with Notepad. Instead, use WordPad and drag the scrollbar down. Skip the first 79,000 mostly blank lines and go to the bottom of the file--there you’ll find a few macro expansions.