Parameterized Algorithms

[Previous] [Next]

If you use C++ templates to model musicians but don't use smart pointers, you'll find that the "coded" musicians behave like real-life musicians—the guitarist, the bass player, and the vocalist are off drinking beer while the drummer is left to carry in all his equipment and to set up before and clean up after the band plays. When modeled using smart pointers, the musicians put down their beers and help the drummer carry in his stuff, set it up, tear it down, and load it again when the band is done playing. Let's take templates a step further and see how to use them to let the client easily change the musicians' behavior; that is, let's use templates to parameterize algorithms performed by the musicians.

In real life, you have to sift through a number of issues when you're starting a band. For example, you'll need to audition prospective band members. In choosing musicians for the band, you'll need to consider all sorts of factors, including the style of each instrumentalist. For example, if you find a guitarist who's really flashy but not a solid rhythm guitarist, you'll need to weigh how that will affect the band's sound. In the example that follows, we'll use C++ templates to model a band that the client (the one putting together the band) can easily modify by applying different template parameters.

Putting Together a Band

To begin, let's consider how the client might put together a band. One way to model a band is to write a template class that accepts types of musicians as template parameters. The CRockBand class would then have a public function to get the musicians to play together. The CRockBand class might look something like this:

 template<class TGuitar, class TBass,           class TDrums, class TVocals> class CRockBand {     TGuitar guitar;     TBass bass;     TVocals vocals;     TDrums drums; public:     void PlayMusic(void) {         guitar.PlayLead();         bass.ThumpAway();         drums.BangAway();         vocals.Sing();     } }; 

The rock band class is pretty straightforward. It takes a drummer, a bass player, a vocalist, and a guitarist as template parameters. The PlayMusic function simply causes each musician to play his own instrument in his own particular style. The client might use the CRockBand class as shown here:

 void ListenToRockBand() {     CRockBand<CGuitarist, CBassist,                CDrummer, CVocalist> NoName;     MessageBox(NULL, "A non-name band is on",                 NULL, MB_OK);     NoName.PlayMusic(); } 

Notice in this example that the client pieces together the band using average Joe musicians off the street.1 When you execute this function, four message boxes come up, each indicating that the four musicians are using their own boring styles. What if the client wants to move away from the boring and forge a rock band from more notable players? We want to give the client the option of forming that kind of band too. To provide the client with this option, we first need to define classes to represent some more interesting players.

Finding World-Class Musicians

Let's start by inventing classes to represent some famous musicians. This class will derive ultimately from CMusician and will represent each player's style through the appropriate member function. The following code presents world-class musicians from the bands Rush and Van Halen:

 class CEddieVanHalen : public CGuitarist { public:     CEddieVanHalen() :         CGuitarist("Guitar") {     }     void PlayLead() {         MessageBox(NULL,                     "Use hammer-ons",                     "Eddie Van Halen", MB_OK);     } }; class CGaryCherone : public CVocalist { public:     CGaryCherone() :         CVocalist("Vocals") {     }     void Sing() {         MessageBox(NULL,                     "Sounds like Extreme",                     "Gary Cherone", MB_OK);     } }; class CAlexVanHalen : public CDrummer { public:     CAlexVanHalen() :         CDrummer("Drums") {     }     void BangAway() {         MessageBox(NULL,                     "Look at the flaming bass drum",                     "Alex Van Halen", MB_OK);     } }; class CMichaelAnthony : public CBassist { public:     CMichaelAnthony() :         CBassist("Bass") {     }     void ThumpAway() {         MessageBox(NULL,                     "Play the Jack Daniels bass",                     "Michael Anthony", MB_OK);     } }; class CAlexLifeson : public CGuitarist { public:     CAlexLifeson() :         CGuitarist("Guitar") {     }     void PlayLead() {         MessageBox(NULL,                     "Use lots of textures",                     "Alex Lifeson", MB_OK);     } }; class CGeddyLee : public CVocalist, CBassist { public:     CGeddyLee() :         CBassist("Bass"),          CVocalist("Vocals") {     }     void Sing() {         MessageBox(NULL,                     "High and screechy",                     "Geddy Lee", MB_OK);     }     void ThumpAway() {         MessageBox(NULL,                     "Intricate bass lines",                     "Geddy Lee", MB_OK);     } }; class CNeilPeart : public CDrummer { public:     CNeilPeart() :         CDrummer("Drums") {     }     void BangAway() {         MessageBox(NULL,                     "Really inventive style",                     "Neil Peart", MB_OK);     } }; 

Each player has a particular style that is represented through a member function. For example, Eddie Van Halen is well known for popularizing two-handed tapping, so when he's called on to play a lead, he does it with lots of hammer-ons. Neil Peart has a distinctive drumming style that is very inventive, which is represented through his BangAway function.

Once the world-class musicians are in place, we can model different bands through the CRockBand class and mix in various musicians.

Inside Atl
Inside ATL (Programming Languages/C)
ISBN: 1572318589
EAN: 2147483647
Year: 1998
Pages: 127 © 2008-2017.
If you may any questions please contact us: