Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 12
Текст из файла (страница 12)
If you’re using floating-point numbers,use TReal for routine scientific calculations: conventional wisdom hasit that TReal32 isn’t precise enough for serious use. Only use TReal32when speed is of the essence and you know that it’s sufficiently precisefor your problem domain.Use TBool to specify a Boolean return value from a function, ratherthan TInt. This conveys more information to anyone trying to read yourcode.
To represent Boolean values, do not use the TRUE and FALSEconstants that are defined for historical reasons in e32def.h; rather,use ETrue and EFalse defined in e32std.h. Be aware that ETrueis mapped to 1 but C++ interprets any integral value as ‘true’ if it isnon-zero, so never compare a value with ETrue:TBool b = something();if (b == ETrue)// Bad!Instead, just rely on the interpretation of Booleans in C++:if (b) { . . .
};And now, the most important rule of all:NAMING CONVENTIONS43Always use the Symbian OS typedefs rather than native C++ types,to preserve compiler independence.The one exception to this rule is related to the C++ void, whichcan mean either ‘nothing’ (as in void Foo()) or ‘anything at all’ (as invoid* p). Symbian C++ uses void for the ‘nothing’ case and TAny* forthe ‘pointer to anything’ case:void Foo();TAny* p;// Returns no result// A pointer to anythingFundamental types also include characters and text. We cover them inChapter 5, along with descriptors, which are the Symbian OS version ofstrings.3.2 Naming ConventionsJust like any system, Symbian OS uses naming conventions to indicatewhat is important and to make source code more readable.
Symbian OSsource code and all SDKs adhere to these conventions.Class NamesA class name should be a noun, as a class represents an object. Classnames use an initial letter to indicate the basic properties of the class; themain ones are shown in Table 3.2.Some other prefixes are occasionally used for classes in rare circumstances. The only one we’ll encounter in this book is HBufC, forheap-based descriptors. Kernel-side programming uses D for kernel-sideCBase-derived classes and C-style structs without any member variables use S.
However, there are very few C-style structs in thelater versions of Symbian OS – the trend is to replace them with Tclasses.The distinction between T, C and R is very important in relation tocleanup and it is discussed in further detail in Chapter 4. In general,T classes do not require cleanup because they allocate no resources; Rclasses acquire resources that need to be closed or released; and C classesneed to be deleted.One thing we need to be honest about here is that some M classesare not pure interfaces, because some of them actually implement code.Nevertheless, the majority of these types are pure interfaces.44SYMBIAN OS C++Table 3.2 Types of Class.PrefixCategoryExamplesDescriptionTTypeTDesC, TPoint,TFileNameT classes do not have a destructor;they act like built-in types.
That’swhy the typedefs for all built-intypes begin with T. T classes can beallocated automatically (if they’re nottoo big), as members of other classesor on the heap.CClassCActive, CBaseAny class derived from CBase. Cclasses are always allocated on thedefault heap. CBase ’s operatornew() initializes all member data tozero when an object is allocated.CBase also includes a virtualdestructor, so that by callingdelete() on a CBase* pointer anyC object it points to is properlydestroyed.RResourceRFile, RTimer,RWriteStream,RWindowAny class that owns resources otherthan on the default heap is an Rclass.
They are usually allocated asmember or automatic variables. In afew cases, they can be allocated onthe default heap. Most R classes useClose() to free their associatedresources.MMixin,interfaceMGraphicsDeviceMap,MEikMenuObserverAn M class is an interface consistingof virtual functions. A classimplementing this interface shouldderive from it. M classes are the onlyapproved use of multiple inheritancein Symbian OS: they act in the sameway as interfaces in Java. The oldtechnical term was ‘mixin’, hencethe use of M.StaticclassUser, Math, Mem,ConeUtilsA class consisting purely of staticfunctions cannot be instantiated intoan object.
Such classes are usefulcontainers of library functions.Data NamesA data name should be a noun, as it represents an object. Data names,except automatic variables, also use a prefix letter to indicate theirpurpose (see Table 3.3).Static members aren’t used in native Symbian OS code (see themore general discussion of writable static data in Chapter 2). GlobalNAMING CONVENTIONS45Table 3.3 Data name prefixes.PrefixCategoryExamplesDescriptionEEnumeratedconstantEMonday,ESolidBrushConstants or values in anenumeration.
If it has a name,the enumeration itself shouldhave a T prefix, so thatEMonday is a member ofTDayOfWeek. Some #defined constants use an E prefix, incircumstances where theconstants belong to a logicallydistinct set.KConstantKMaxFileName,KRgbWhiteConstants of the #define orconst TInt type. KMax -typeconstants tend to be associatedwith length or size limits:KMaxFileName, for instance,is 256 (characters).iMembervariableiDevice, iXAny non-static membervariable should have an iprefix.
The i refers to an‘instance’ of a class.aArgumentaDevice, aXAny variable declared as anargument. The a stands for‘argument’, not the Englishindefinite article so it isimportant to remember not touse an for words that beginwith a vowel (i.e., aOriginnot anOrigin).Automaticvariabledevice, xAny variable declared as anautomatic (a variable that iscreated automatically when itis required and destroyed whenit goes out of scope)variables, such as console, have no prefix but are generally consideredbad practice and are best avoided altogether.
Some authors use initialcapitals for global variables, to distinguish them from automatics; otherauthors use an initial lower case g. We have no strong views on theright way to do things here. This is mostly because in Symbian OSwe prefer to avoid the issue by avoiding the use of global variablesaltogether.The i convention is important for cleanup. The C++ destructor takescare of member variables, so you can spot over-zealous cleanup code,such as CleanupStack::PushL(iMember) by using this namingconvention.46SYMBIAN OS C++Function NamesAs a matter of convention, you would normally use a verb for a function’sname (as it represents an action).
In addition, the initial letter should beuppercase: Draw(), Intersects().A leaving function should end with L: CreateL(), AllocL(),NewL(), RunL(). A leaving function is essentially used for light-weightexception handling. It may need to allocate memory, open a file ordo some other operation that might fail (because there are insufficientresources or other environment-related conditions – not programmererrors).
When you call a leaving function, you must always considerwhat happens both when it succeeds and when it leaves; you mustensure that both cases are handled. The cleanup framework in SymbianOS is designed to allow you to do this.An LC function (AllocLC(), CreateLC(), OpenLC(), NewLC())leaves something on the cleanup stack when it returns. Commonly, thisis a pointer to an allocated object, but more generally it’s a cleanup item.If the function fails, then it leaves.Simple ‘getter’ functions get some property or member data of anobject. Often a getter is used when the member is private.
Its nameshould be a noun, corresponding with the member name: Size(),Device(), ComponentControl().Complex ‘getter’ functions get some property that requires more workand perhaps even resource allocation. Resource-allocating getters shouldcertainly use Get as a prefix (GetTextL()); other than that the boundarybetween simple and complex getters is not fixed.‘Setter’ functions set some property of an object: SetSize(), SetDevice(), SetCommandHandler(), SetCharFormatL(). Some setters simply set a member; some involve resource allocation, which mayfail, and are therefore also L functions.Macro NamesSymbian OS uses the usual conventions for C preprocessor macro names:upper-case letters and words joined with underscores, for example,IMPORT_C and EXPORT_C.For build-dependent symbols, use two leading and trailing underscores (__SYMBIAN32__ , __WINSCW__).
The symbols _DEBUG and_UNICODE are notable exceptions to this rule. Double underscores arealso used to indicate guards.Indentation, Line Breaks and BracketingIn addition to the naming rules presented so far, there are a number of stylerules that are intended to improve readability by ensuring some degreeof conformity in the appearance of the source code.
Please note that theNAMING CONVENTIONS47rules presented in this section make more sense when put together ratherthan when considered individually. Therefore, it makes little sense to tryto memorize them all. They are given here for reference; the best way toget used to them is by day-to-day usage and by looking at the examplesthroughout this book (although this section contains an example that triesto include as many of them as possible).• Use a new line when opening a curly bracket.• The opening bracket should occupy a new line with nothing else on itand be indented by one tab space in comparison to the previous line.Throughout this book, because of the narrow line width, we haveindented by two spaces rather than a full tab.• Any code within curly brackets must be at the same indentationlevel as the brackets. (An exception to this is the access qualifiers formembers in a class declaration.)• The closing bracket must be at the same level of indentation as theopening bracket and must occupy a line on its own.