Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 17
Текст из файла (страница 17)
TPtrC contains a pointer, but itonly uses (rather than owns) the characters it points to, so it does notneed a destructor.T classes do not own any data, so they don’t need a destructor. Theymay have pointers, provided that these are ‘uses-a’ pointers rather than‘has-a’ pointers.T classes are normally allocated as automatics, or as member variablesof any other kind of class.It’s possible (but rare) to allocate T-class objects explicitly on the heap.If so, you need to ensure that the heap cell is freed. You can push a T-classobject to the cleanup stack as in the following example (see Section 4.4for more detail).TDes* name = new (ELeave) TBuf<40>; // TDes is a base of TBufCleanupStack::PushL(name);DoSomethingL();CleanupStack::PopAndDestroy();// nameA T-class object can usually be assigned using a bit-wise copy.Therefore, T types do not need copy constructors or assignment operators(except in specialized cases, such as copying one TBuf to another, wheremaximum lengths of the TBufs may differ).Since C-class objects reside on the heap and are referred to by pointers,they are passed by reference, that is, by copying the pointer.
Thus C classesdo not need a copy constructor or an assignment operator.As a result, C++ copy constructors and assignment operators areextremely rare in Symbian OS.R ClassesThe next category is classes whose names begin with R, which standsfor ‘resource’. Usually, R-class objects contain a handle to a resourcethat’s maintained elsewhere. Examples include RFile (maintained by thefile server), RWindow (maintained by the window server), and RTimer(maintained by the kernel).The R object itself is typically small; as a minimum, it contains onlya resource handle. A function in an R class doesn’t usually change themember data of the R class itself; rather, it sends a message to thereal resource owner, which identifies the real object using the handle,performs the function, and sends back a result.
Functions such as Open()and Create() allocate the resource and set the handle value. Typically,68OBJECTS – MEMORY MANAGEMENT, CLEANUP AND ERROR HANDLINGa Close() function frees the resource and sets the handle value to zero.A C++ constructor ensures that the handle is zero to begin with.A few R classes do not obey the conventions described here. We willpoint out such classes as we encounter them.R classes are like T classes in some ways, and like C classes in others.• Like T classes, R classes can be automatics or class members. Alsolike T classes, they can be copied (which just copies the handle), andthe copy can be used like the original.• As with T classes, it is very rare to refer to R classes using pointers.They are usually passed by value or by reference.• Like C classes, R classes own resources: that is, they contain pointers toresources and are responsible for allocating and deallocating memoryfor them.
Although R classes don’t usually have a destructor, they dohave a Close() function that has a similar effect, including settingthe handle to zero, which is rather like zeroing the pointer to a C-classobject. It’s safe to call Close() twice – on an already closed R-classobject it has no effect.• Like C classes, R classes are expected to zero-initialize their handlevalue, so that functions can’t be used until the handle is initialized.Note, however, that the zero-initialization must be explicitly coded,in their constructor (as is the case for all system R classes).
There is noRBase corresponding to CBase.R classes as member variablesR-class objects are often members of a C-class object. Consider thefollowing example of a C class with a member variable iFs of type RFs(a file-server session handle). Its file deletion code could be written asfollows:case EDeleteFile:{User::LeaveIfError(iFs.Connect());User::LeaveIfError(iFs.Delete(KTextFileName));iFs.Close();}It’s important for the C++ destructor of the containing C class toinclude a call to iFs.Close(), so that the RFs is closed even if thedelete operation fails.CLASS CATEGORIES IN SYMBIAN OS69M ClassesThis particular type of class was designated in order to enable an easymechanism for multiple inheritance.
M classes are typically abstract, sothey never get instantiated in their own right. Consequently, the case ofmemory being allocated for an M-class object is practically non-existent.M classes are used for packaging behavior (rather than data) in are-usable manner; the prefix M stands for ‘mixin’. An M class can becombined any number of times with different base classes (typically Cclasses).
The derived classes (also C classes) all share the behavior butalso have their peculiar characteristics.Usage of M classes for derivation is the only type of multiple inheritanceallowed in Symbian OS.A typical usage pattern for M classes is shown below. The mixin classcontains some re-usable behavior that we want to pass down to otherclasses consistently.class MSomeMixin{virtual void CommonBehaviour1(TInt aParam) = 0;virtual void CommonBehaviour2(TInt aParam) = 0;};We have the following base classes:class CBaseClassA : public CBase{public:TInt FuncA1();TInt FuncA2();protected:void ConstructL();};class CBaseClassB : public CBase{TInt FuncB1();TInt FuncB2();protected:void ConstructL();};We can then define the following classes:class CDerivedClassA : public CBaseClassA, MSomeMixin;class CDerivedClassB : public CBaseClassB, MSomeMixin;70OBJECTS – MEMORY MANAGEMENT, CLEANUP AND ERROR HANDLINGIn this case, CDerivedClassA and CDerivedClassB are bonafide C classes, because they ultimately derive from CBase.
For memoryallocation, creation and destruction, the same rules apply as for anyother C class. However, they also both share the common functionalitydefined in MSomeMixin. This means that any changes in MSomeMixinwill affect both derived classes.It is of course possible to combine M classes with classes of other type,such as R classes.class RBaseClassA;class RBaseClassB;class RDerivedClassA : public RBaseClassA, MSomeMixin;class RDerivedClassB : public RBaseClassB, MSomeMixin;In this case, the derived classes are also R classes, and are handled inthe same way as all other R classes.4.3 Error HandlingIn machines with limited memory and resources, such as those for whichSymbian OS is designed, error handling is of fundamental importance.Errors are going to happen, and you can’t afford not to handle themcorrectly.Symbian OS provides a framework for error handling and cleanup.
It isa vital part of the system, with which you need to become familiar. Everyline of code that you write – or read – will be influenced by thinkingabout cleanup. No other Symbian OS framework has as much impact.Because of this, we’ve made sure that error handling and cleanup areeffective and very easy to do.In addition to the error handling mechanisms discussed in this chapter,it is possible from Symbian OS version 8.1b onwards to use the standardC++ exception handling facilities. This makes it easier for developersto port their existing (non-Symbian OS) code into Symbian OS.However, we still recommend that developers should use the richer,better tested and more tightly integrated set of Symbian OS-specificerror-handling mechanisms discussed in this section.What Kinds of Error Can the Framework Handle?The first and most obvious type of error to consider is the out-of-memoryerror.ERROR HANDLING71These days, desktop PCs come with at least 512 MB of RAM, virtualmemory swapping out onto 60 GB or more of hard disk, and with userswho expect to perform frequent reboots.
In this environment, runningout of memory is rare, so you can be quite cavalier about memory andresource management. You try fairly hard to release all the resources youcan, but if you forget, then it doesn’t matter too much: things will getcleaned up when you close the application, or when you reboot. That’slife in the desktop world.By contrast, Symbian OS phones have as little as 16 MB of RAM, andoften no more than 32 MB, although there are now devices with 64 MB.By comparison with a PC this is small, and there is no disk-backed virtualmemory, nor are the users used to having to reboot frequently.There are some key issues here that don’t trouble modern desktopsoftware developers.• You have to program efficiently, so that your programs don’t use RAMunnecessarily.• You have to release resources as soon as possible, because you can’tafford to have a running program gobble up more and more RAMwithout ever releasing it.• You have to cope with out-of-memory errors.