Previous | Table of Contents | Next |
![]() | When an object is defined as local to a function, its destroyed as soon as the function terminates. Global objects terminate when the program ends. |
The general problem is that theres a need to take certain actions when the object is created and later when its destroyed. Fortunately, C++ makes object initialization and cleanup easy by providing constructors and destructors. These special member functions control how an object is created or destroyed. The naming syntax is unusual: for a given class,
Our string class is named CStr, so the constructor and destructor are named CStr and ~CStr, respectively:
class CStr { char *pData; int nLength; public: CStr(); // Constructor ~CStr(); // Destructor char *get(void); int getlength(void); void cpy(char *s); void cat(char *s); };
Constructors and destructors have some quirks, One quirk is that they have no return type of any kindnot even void. This is an apparent exception to the rule that every C++ function must have a return type. Another quirk is that the argument lists are left blank rather than using void.
The function definition for the constructor initializes the two class variables as well as allocates a one-byte string that consists of a single null terminator:
CStr::CStr() { pData (char *) malloc(1); *pData \0; nLength = 0; }
Odd, isnt it? The name CStr appears twice in the function heading. The first occurrence of CStr should be taken together with the scope operator (::) as an indicator that this function is a member of the CStr class. So CStr:: is a prefix. The second occurrence of CStr is the name of the function itself.
The destructor is simpler. All it has to do is to give the current memory block back to the system by calling the free function. Remember that the name of the function is ~CStr.
CStr:: ~CStr() { free(pData); }
Destructors tend to be somewhat cut and dried: all a destructor does, generally, is to free any loose system resources hanging around; then it ends. Constructors, however, have more interesting possibilities. Youll learn more about them in the next chapter, Another Look at Constructors.
OK, you say, encapsulation sounds wonderful, but its too inefficient. Remember, encapsulation is the idea that internals such as pData and nLength cannot be accessed from outside. The user of an object has to call public functions to get at the values.
Encapsulation has many benefits, but it also means that you often end up with one-line functions such as these:
char *CStr::get(void) { // Return ptr to string data. return pData; } int CStr::getlength(void) { // Return length. return nLength; }
Theres a certain overhead associated with each function call, so calling a function rather than just getting a value slows down performance. Fortunately, C++ provides an optimal solution: inline functions. The term inline refers to expanding something directly into the body of the code (that is, placing it inline) rather than executing a jump via the processors CALL instruction. For extremely short functions, the inline approach is ideal. In this case, if getlength were an inline function, then the compiler would, in effect, replace this statement:
x = string1.getlength();
with this:
x = string1.nLength;
This arrangement eliminates function-call overhead and preserves execution speed.
Normally, this second C++ statement would be illegal (nLength is private and cant be accessed), but because nLength was accessed through a public member, getlength, there is no problem. The inline function approach preserves both encapsulation and efficiency.
In C++, functions are automatically inlined when you place them inside the class declaration. Here this is done for get and getlength:
class CStr { char *pData; int nLength; public: CStr(); // Constructor ~CStr(); // Destructor char *get(void) {return pData;} int getlength(void) {return nLength;} void cpy(char *s); void cat(char *s); };
Despite their brevity, get and getlength are functions and obey almost all the same syntax rules as normal functions do. Each of them could have had more than one statement if you chose, although most inline functions are very short. Note that, as with standard function definitions, the closing brace in these function definitions is not followed by a semicolon.
Previous | Table of Contents | Next |