Dumb Pointers

[Previous] [Next]

Consider a regular C++ pointer. The traditional C++ literature calls the pointers built into C++ "dumb" pointers. That name might not be very nice, but it does accurately describe them. Normal C++ pointers don't do much except point to things. The client is often responsible for seeing to such details as pointer initialization.

To illustrate the problems with dumb pointers, let's study the example shown here, which uses a C++ class to model a musician:

 class CMusician { protected:     CMusician(){} // Never use a default constructor. public:     CMusician(char* szInstrument) {         strcpy(m_szInstrument, szInstrument);     }     ~CMusician() {         MessageBox(NULL,              "Elvis has just left the building",              NULL, MB_OK);     }     virtual void Play() {         MessageBox(NULL, "Makin' music. Drums set up?",                     m_szInstrument, MB_OK);     }     char m_szInstrument[256]; }; 

The musician objects are constructed using the name of the instrument each musician plays. (A more complete example would probably do more than simply label the musician as someone who plays a particular instrument.) Notice that the CMusician class has a function to play music—the Play function. Now imagine some client code that looks like this:

 void UseMusician() {     CMusician* pMusician;     // You need to initialize the musician pointer at      //  some time. But what if you forget to do it now,     //  and then later do something like this:     if (pMusician) {         // Get ready for fireworks because pMusician is         //  NOT NULL, but it points to some random data.         pMusician->Play();     } } 

In this case, the client code forgot to initialize the pMusician pointer to NULL. (Of course, this never happens in real life!) Because pMusician contains a non-NULL value (it's actually whatever value happened to be on the stack at the time), the test to make sure the pointer is valid succeeds (when in fact it should fail). The client gleefully proceeds, believing all is right in the world. At best, the client will experience unexpected results; at worst, the client will crash. The unpredictable consequences are possible because the client is "calling into darkness." (Who knows where pMusician is pointing—probably not to anything even resembling a musician.) Naturally, we'd like a mechanism for ensuring that pointers are initialized. We'll see one technique for making sure this happens—using "smart" pointers—in a moment.

Now imagine a second scenario. Perhaps you'd like to plug a little extra code into the musician class to perform an operation common to all musicians. For example, let's say you'd like all the musicians to help the drummer unload and set up his equipment before they begin playing. And maybe the musicians should also help the drummer clean up after the gig is over. Consider the musician example above. When the client calls the Play function, the musician starts playing before the drummer has set up properly, leaving the poor client unable to dance. What we'd like to do is add a generic hook to the musician class so that it can make sure the drummer is set up before the rest of the band begins to play.

The C++ solution to coping with these problems is called a smart pointer.

Inside Atl
Inside ATL (Programming Languages/C)
ISBN: 1572318589
EAN: 2147483647
Year: 1998
Pages: 127

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net