home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * meal3.cpp - - Final attempt at Object Oriented Design.
- *
- *
- * Taken from The C Users Journal
- *
- * "Pricing A Meal: An Object-Oriented Example In C++"
- * by Chales Havner
- *
- * August 1990 Volume 8, Number 8
- *
- * Comments by the author:
- * "C++ 2.0 allows virtual function declarations to be followed by =0;. This
- * somewhat strange syntax means every derived class must implement the
- * function or again define it as pure virtual. The compiler checks the
- * declarations and issues an error message if this is not so. The compiler
- * check ensures that we don't inadvertently leave out the cost () function."
- *
- * "This third version adds some new features. This week all diserts are 25%
- * off except for Pies. By adding a virtual discout () function to the
- * Dessert abstract class we automatically, via inheritance, apply it to all
- * derived desserts. The Meal class's cost function was changed to multiply
- * the dessert cost (d->cost ()) by the discount (d->discount())."
- *
- * "Since pies are the only desserts that have no discount, a discount ()
- * multiplier of 1.0 is placed in the Pie_obj class. Every object has a
- * text () function to print information about itself. The Meal::print ()
- * member function in Listing 3 uses the standard stream I/O, which is type
- * safe, instead of printf (). In general, using cout, cin and cerr via the
- * overloaded insertion << asnd extraction >> operators are safer than
- * printf () and you can easily overload the operators for new class types
- * you create; printf () only knowns about built-in types like double and
- * char *. However, overloading operators is material for another article."
- *
- * "The final design is clean and elegant. The class framework models the
- * real world problem domain directly. Adding calorie information would be
- * much like cost. The class hierarchy actually needs to be deepened further
- * to represent different kinds of cakes and pies. Instead of an item's cost
- * residing in the object, the cost () member function could access a
- * database to fetch the most recent price increase. This short example
- * demonstrates just some of what OOP (and C++ in particular) has to offer."
- */
-
-
- #include <iostream.h>
- #include <stdio.h>
-
-
- enum ENTREE { Steak, Fish};
- enum DESSERT { Pie, Cake, Jello };
- enum APPETIZER { Melon, ShrimpCocktail };
-
-
- /////////////////////////////////////////////////////////////////////////
-
- class Dessert // An abstract class
- // - never instantiated by itself
- {
- public:
- virtual double cost () = 0; // pure virtual ==> abstract class
- virtual double discount () { return .75; } // 25% off
- virtual const
- char *text () = 0;
- };
-
-
- class Jello_obj : public Dessert
- {
- public:
- double cost () { return .60; }
- const char *text () { return "Jello "; }
- };
-
- class Pie_obj : public Dessert
- {
- public:
- double cost () { return 1.50; }
- double disccount () { return 1.00; } // no discount
- const char *text () { return "Pie "; }
- };
-
- class Cake_obj : public Dessert
- {
- public:
- double cost () { return 1.00; }
- const char *text () { return "Cake "; }
- };
-
- /////////////////////////////////////////////////////////////////////////
-
- class Entree
- {
- public:
- virtual double cost () = 0;
- virtual const
- char *text () = 0;
- };
-
- class Fish_obj : public Entree
- {
- public:
- double cost () { return 4.00; }
- const char *text () { return "Fish "; }
- };
-
- class Steak_obj : public Entree
- {
- public:
- double cost () { return 7.50; }
- const char *text () { return "Steak "; }
- };
-
- /////////////////////////////////////////////////////////////////////////
-
- class Appetizer
- {
- public:
- virtual double cost () = 0;
- virtual const
- char *text () = 0;
- };
-
- class Cocktail_obj : public Appetizer
- {
- public:
- double cost () { return 2.00; }
- const char *text () { return "Cocktail "; }
- };
-
- class Melon_obj : public Appetizer
- {
- public:
- double cost () { return .85; }
- const char *text () { return "Melon "; }
- };
-
- /////////////////////////////////////////////////////////////////////////
-
- class Meal
- {
- Appetizer *a;
- Dessert *d;
- Entree *e;
-
- public:
- Meal (APPETIZER = Melon, ENTREE = Fish, DESSERT = Jello);
- ~Meal ();
- double cost ();
- void print ();
- };
-
-
- /////////////////////////////////////////////////////////////////////////
-
- double Meal::cost () { return (d->cost () * d->discount () +
- a->cost () + e->cost ()); }
-
- Meal::Meal (APPETIZER aval, ENTREE eval, DESSERT dval)
- {
- if (aval == Melon) a = new Melon_obj;
- else a = new Cocktail_obj;
-
- if (dval == Jello) d = new Jello_obj;
- else if (dval == Pie) d = new Pie_obj;
- else d = new Pie_obj;
-
- if (eval == Steak) e = new Steak_obj;
- else e = new Fish_obj;
-
- }
-
- Meal::~Meal () { delete a; delete e; delete d; }
-
-
- void Meal::print ()
- {
- cout << a->text () << e->text () << d->text () << ", Meal Cost = " <<
- a->cost () + e->cost () + d->cost () * d->discount () << "\n";
- }
-
- /////////////////////////////////////////////////////////////////////////
-
- void main (void)
- {
- Meal m1 (Melon, Fish, Jello);
- Meal m2 (Melon, Steak, Cake);
- Meal m3 (ShrimpCocktail, Steak, Cake);
-
-
- m1.print ();
- m2.print ();
- m3.print ();
- }