Previous Page TOC Next Page



- 19 -
Object-Oriented Programming



What You'll Learn


Until now, the programming you have done has been "traditional" programming. In the last lesson, you saw that working with structures and memory allocation started to get complicated, especially when keeping track of all that memory. In this lesson, you'll see that C++ provides you with a number of useful tools to help you contain this complexity.

The gathering of a number of special techniques has come to be called object-oriented programming (OOP). In this unit, you will see what this really means and start learning some new C++ tricks.

OOP Buzzwords


When working with computers, it is very important to be fashionable! In the 1960s, the new fashion was what were called high-level languages such as FORTRAN and COBOL, in which the programmer did not have to understand the machine instructions. In the 1970s, people realized that there were better ways to program than with a jumble of GOTO statements, and the structured programming languages such as PASCAL were invented. (PASCAL looks and works much like the C++ you have seen so far.) In the 1980s, much time was invested in trying to get good results out of fourth-generation languages (4GLs), in which complicated programming structures could be coded in a few words (if you could find the right words with so many words to choose from). There were also schemes such as Analyst Workbenches, which made systems analysts into highly paid and overqualified programmers. The fashion of the 1990s is most definitely object-oriented programming.

Read any book on object-oriented programming, and the first things you will read about are three words:

Well, that's enough to scare you away from OOP before you start! Don't panic, though. Before you do the spelling test at the end of the unit, take comfort in the fact that only the most difficult to spell, polymorphism, is a really novel programming language feature. As you will see, there is not much in OOP that isn't common sense, although it might seem to be black magic at first.

Let's take a look at each one of those words and find out what they really mean.

Encapsulation


Definition

Encapsulation means hiding away the workings of your code.

Encapsulation means that you hide away the inner workings of your system and present a well-defined interface to the rest of the world that tells it only what it needs to know.

A good real-world example of encapsulation is a wristwatch. It is important to know what the time is. The way your watch keeps time—whether it is battery-powered or has a spring and lots of cogs—is not important as long as the accuracy is there. You look at the face, and that tells you all you need to know.

Writing good code means not only that it is fast and does what it is supposed to do (bug-free), but also that it can easily be maintained and amended. Over the years, programmers have come to recognize that hiding the workings of one piece of code away from another helps the programmer change code, fix errors, or improve its workings without breaking some piece elsewhere in the program.

Another example of encapsulation is the PC that you've been doing battle with over the lessons in this book. IBM-compatible PCs are examples of a set of encapsulated hardware systems. You can buy screens, printers, and disk drives from different sources and plug them together, and they work. You might have spent three weeks trying to install your sound card last month, but normally it is simple. When a standard interface has been defined to the rest of the electronic jungle that is your PC, you have a fighting chance. You can buy a bigger screen and a laser printer to replace your dot-matrix printer, plug them together, and they talk. The different units know how to talk to each other; you don't need to wire your disk drive into your screen and your printer into the sound card to make everything work. (That might seem like a stupid remark, but real programmers often write code that does the software equivalent of just that.) When the workings of a device have not been successfully encapsulated, your troubles begin.

Inheritance


Definition

Inheritance is the capability to borrow pieces of code to reuse.

Inheritance is the process of taking an object that does most of the job that you want it to do and adding some extra bits to do a more useful or specialized job. For instance, in the example of the wristwatch, you could take an ordinary wristwatch and add a date display to it. The world of consumer durables does this all the time—taking a basic model and adding extra features that give lots of added value for very little effort on the manufacturer's part.

It is a lot easier to build a car with an automatic gearbox by throwing away the old manual gearbox and adding a new automatic box, than it is to design a complete car from scratch. You might need to throw away some old parts, but usually the car designer has taken the option into account in the first place. The extra benefit is that if the designer wants to change features of the two "different" cars, he can change a single design and both versions are updated. In the world of programming, Visual C++ gives you some tools to easily borrow some code you have already written and add or change parts. If the underlying way it works is changed, only one set of code needs changing.

Polymorphism


Definition

Polymorphism is the capability to ask different objects to perform the same task and have the object know how to achieve that task in its own way.

Polymorphism is the most novel idea in OOP. It is easiest to explain by an example. You can press the Play button on a CD player, VCR, or cassette player and each will play some sound (one will also give you a picture). You don't have to understand how they work; you just understand the interface.

In Visual C++, this is implemented so that you can ask an object to perform a function, and depending on what type of object you ask, the function responds in a different way. The classic programming example is that of a graphics program in which you create objects such as circles, rectangles, and triangles. The drawing program is written to store shapes and know where the shapes should be placed on the drawing. When it is time to print, it only has the code to tell the object where to print, and it asks each object to draw itself in the right place. By defining the right interface, the program can be provided with more and more shapes and the main program does not need to change.

Why Is OOP Important?


Definition

Object-oriented programming is a productivity tool.

So you have read about all of these wonderful concepts. Why choose these features? Each of these features is a step on the road to reliable and productive programming. By using prebuilt libraries of code, you can save time and still have the flexibility of altering the way that they work to suit your own needs. Comparing C++ with C, you will find that there are lots of extra features that encourage putting thought into structuring programs so that they are more maintainable. By gathering code into what C++ calls classes, the language helps you divide large programs into small manageable sections, in the same way that you divide small programs into functions. This is very important, because the difficulty of understanding pieces of code increases exponentially (in other words, a lot!) as the pieces of code get bigger and bigger. C++ does not guarantee productivity and maintainability, but it provides you with some tools to help you along the path.



There is no Stop and Type here due to the textual nature of this section.


Moving from Structures to Classes




The class is the cornerstone of object orientation in Visual C++.

Cast your mind back to when we looked at structures. Do you remember the comment about a structure being a gathering of related data items? With a quick change in terminology, you can change a structure into a class and a structure variable into an object. An object needs two things:

You already know how to make class data. In C++, a structure is a special case of a class. To make a class, change the struct keyword to class and add a special extra label, public, and you've done it!


class C

  {

    public:

      int   i;

      float f;

      char  str[30];

  };

Remarkable! It is almost identical to a dull old structure, but now it is a shiny new object-oriented class. Don't worry about that public word yet; we'll deal with that before the end of the unit. Just don't miss it. What's the catch? There isn't one! Let's define an object:


C anObjectOfTypeC;

So you've created an object called anObjectOfTypeC. All the rules for accessing data members are the same as for structs. Let's not labor the point and move straight to what's new about classes.

Member functions




A class can hold functions as well as data

Recall, back in Lesson 9, that you built a program dealing with contacts (Listing 17.2). There were two functions in this program that were prototyped like this:


int AddContact(Contact& contact);

void DisplayContact(const Contact& contact);

Both of these functions had the sole purpose of taking a Contact struct (or a contact object) and providing a function that used that object. All they need to know is what Contact they are operating on. You want to tidy up your program so that all the code is encapsulated and related. At the moment, these functions are available globally, but they are useless without a Contact object. Visual C++ provides a way of declaring the function so that it is only available when there is a class object to use it with.



A function that is part of a class is called a member function, in the same way that a variable is called a data member.


class Contact

  {

    public:

      char name[50];

      int  age;

      char phoneNo[15];

      void AddContact();

      void DisplayContact();

  };

The only odd thing about these declarations is that the Contact object has been removed. This is because, to use member functions, you use the member access operators—the dot operator (.) and the pointer operator (->)—to tell Visual C++ which data to work on. In main() the code could look like this:


Contact contact;

contact.Add();

contact.Display();


That looks familiar! Now you understand what those funny cout.precision() calls were about.

The class definition only declares the member function; it does not define how the function works. It is time to meet a new operator, ::, which is called the scope operator. If you try to define the functions as before, Visual C++ lets you, but all sorts of problems will arise because Visual C++ doesn't realize that you meant to define the member functions. You tell Visual C++ the class that the function belongs to by adding the class name and scope operator to the function name.


void Contact::Display()

  {

     // body of function


The class name precedes the function name, not the return type.

Now that you have taken away the Contact parameter, you need to access the members in a different way. In a member function, Visual C++ knows which object was used when calling the function, so member access is easy. Within a member function, you can access all the class data members and member functions directly, and you get the data for the object that calls that member function:


void Contact::Display()

  {

    cout << "Name : " << name << endl;

    cout << "Age  : " << age << endl;

You can access member functions in the same way that you access the data members.

We've covered enough to look at an example. Let's turn the contact program into an object-oriented version in Listing 19.1.

Input Listing 19.1. An object-oriented contact program.

  1:// Filename: CONTACTO.CPP

  2:// Allow the display and entry of contacts

  3:// using OOP techniques

  4://

  5:#include <iostream.h>

  6:

  7:class Contact

  8:  {

  9:    public:

 10:     char name[50];

 11:     int  age;

 12:     char phoneNo[15];

 13:

 14:     // Member function declarations (prototypes)

 15:     void AddContact();

 16:     void DisplayContact() const;

 17:  };

 18:

 19:// Maximum number of contacts

 20:const int MAXCONTACTS = 10;

 21:

 22:// Global Prototypes

 23:void DisplayAllContacts(const Contact contacts[MAXCONTACTS],int count);

 24:

 25:void main()

 26:  {

 27:    Contact contacts[MAXCONTACTS];

 28:    char answer;

 29:    int count = 0;

 30:    while( count < MAXCONTACTS )// while more room

 31:      {

 32:         // Ask the user if they want to continue

 33:         cout << "Do you want to add a contact [Y]es/[N]o: ";

 34:         cin >> answer;

 35:         cin.ignore(80,'\n'); // skip rubbish

 36:

 37:         if (answer == 'y' || answer == 'Y')

 38:           {

 39:             // Add the information

 40:             contacts[count].AddContact();

 41:             count++;

 42:           }

 43:         else

 44:           break;

 45:      }

 46:

 47:    DisplayAllContacts(contacts,count);

 48:

 49:  }

 50://

 51:// DisplayContact displays a single name

 52://

 53:void Contact::DisplayContact() const

 54:  {

 55:    cout << endl;

 56:    cout << "Name    : " << name << endl;

 57:    cout << "Age     : " << age << endl;

 58:    cout << "phone no: " << phoneNo << endl;

 59:    cout << endl;

 60:  }

 61://

 62:// DisplayAllContacts calls DisplayContact to show

 63:// all entered names

 64://

 65:void DisplayAllContacts(const Contact contacts[MAXCONTACTS],int count)

 66:  {

 67:    for (int i = 0; i < count; i++)

 68:      {

 69:        contacts[i].DisplayContact();

 70:      }

 71:  }

 72://

 73:// Add contact asks for one contact

 74://

 75:void Contact::AddContact()

 76:  {

 77:    cout << "Name: ";

 78:    cin.getline(name,30);

 79:    cout << "Phone no: ";

 80:    cin.getline(phoneNo,15);

 81:    cout << "Age ";

 82:    cin >> age;

 83:    cin.ignore();

 84:  }

Output


Do you want to add a contact [Y]es/[N]o: y

Name: Ian Spencer

Phone no: 0-672-30600-X

Age 36

Do you want to add a contact [Y]es/[N]o: y

Name: Konrad Borkowy

Phone no: Ex-directory

Age 41

Do you want to add a contact [Y]es/[N]o: y

Name: Wendy Smith

Phone no: 111-1111

Age 40

Do you want to add a contact [Y]es/[N]o: no

Name    : Ian Spencer

Age     : 36

phone no: 0-672-30600-X

Name    : Konrad Borkowy

Age     : 41

phone no: Ex-directory

Name    : Wendy Smith

Age     : 40

phone no: 111-1111

Analysis

The program works much the same as it did last time. Let's go through the special OOP differences. Lines 7 to 17 declare the class. The only differences are the public label on line 9 and the member functions in lines 15 and 16. These function declarations are similar to the global declarations. There is an extra feature on DisplayContact. In the original CONTACT.CPP, DisplayContact() took a constant parameter. Because there is no parameter, C++ needs a new way to say "I will not change the object I'm operating on." This is done by adding an extra const keyword after the function name (in both the declaration in line 16 and the definition in line 53).

Note that the definition in line 53 uses the scope operator (::)to tell C++ which class this function definition belongs to. This means that you can have the same function in different classes and C++ can tell them apart.

The main() code is very similar to the original program. Notice that the main() code does not reference any of the object's data items. All the data items are referenced in the member code of AddContact() and DisplayContact(). The interesting part of the code in the member functions is that within a member function, the function has access to the class member data items without qualification—for example, name in line 56.

There is nothing stopping the code in main() from directly accessing the data members of the class. This is a source of great danger, and you haven't gained a great deal of safety from putting the code into the class.



In this book, I have not used header files for the code. Normally, a C++ programmer places the class definition (such as lines 7 to 17 in the previous code) in a header file called CONTACT.H. Then the definition is included by using #include "contact.h" in the main code. The quotation marks mean that C++ should look for the file in the current directory first. This enables you to split code that uses the class into many CPP files rather than having one long file. You can build several files into one executable by using the Visual Workbench's project facility. (Projects are explained in a comprehensive section in the Visual Workbench online help, which you can easily find from the help contents page.)


Access To Members




Classes have a new sort of scope: class scope.

When writing code within a member function, the code can access all the members of the current object as if they are local variables. How does Visual C++ decide which object's members the function is working with when there is more than one member? The access to members is always with the object that the function is called with, as in the following example:


class A

  {

     public:

       int x;

       void SetX(int X);

       int GetX();

  };

void A::SetX(int X)

  {

     x = X;

  }

int A::GetX()

  {

     return x;

  }

void main()

  {

    A a1;

    a1.SetX(5);

    A a2;

    a2.SetX(10);

    int y = a1.GetX();

    int z = a2.GetX();

  }

In each access of the class member function, the programmer specifies which object the member function is associated with. So although GetX() only refers to x inside the function, C++ knows to access a1.x or a2.x because the function, when called, remembers which object was referred to.

Even though you have class functions, you can still access the members in the normal way. Outside member functions (or outside class scope), you need the member access operators; inside the class, access is given automatically.

However, you need to remember one of our long words, encapsulation. If everyone can get at data members, there is no advantage to classes over structures. To control access to both data members and function members, Visual C++ provides the access labels public, protected, and private to declare what is available to the world outside the member functions. public means that the members are available for access by the class member access operators; private and protected are only available to member functions. A class can contain as many of these access labels as you like.

The reason for having private members is that the class can ensure that only sensible values are set. For example, a Person class might have an age member. If age was a public member, any programmer could set the age to an unreasonable amount. If age is private, the only functions that can access age are the classes own functions. This doesn't mean that the age can't be set from outside the class, only that it has to be set by passing a parameter of a member function and then assigning it into the member. Similarly, to get a private member out, another accessing function is provided. This provides two benefits:

If age has a wrong value, only the class member functions need to be looked at to understand how this could happen. Correcting this might mean adding code into the access functions to validate the data passed to the class by the function. After the access functions are provided, the class can change the way the data member is held, and the outside world need not be aware of the change. For example, your Person class might hold a date of birth. Externally, it might be convenient to pass this as a character array; internally, it might be better to hold it as a number for calculations. The outside world never needs to know that the date is held as a number, as long as the access functions know how to convert the data.



Member functions provided just for giving and receiving data are known as access functions.

A struct is not really a separate mechanism in C++. It is a special case of the class. The difference between a struct and a class is that in a struct, the default access without a label is public, and the default access for a class is private. By convention, structs are only used to represent a data-only class.

The final listing of this section, Listing 19.2, shows a simple class for handling retirement ages.

Input Listing 19.2. Looking forward to a quiet life.

  1:// File name: PERSON.CPP

  2:// A simple class for handling age of a person

  3://

  4:#include <iostream.h>

  5:#include <string.h>

  6:

  7:// Class declaration

  8:class Person

  9:  {

 10:            // Public - available like a struct member

 11:    public:

 12:            // Set up data

 13:      int AskForPerson();

 14:      void SetRetirementAge(int year);

 15:            // Get the name, but const char * stops the

 16:            // pointer being used to change the name

 17:            // and the following const after GetName means

 18:            // that the class will not be changed by calling

 19:            // this function

 20:      const char * GetName() const;

 21:      int GetAge() const;

 22:      int YearsToRetirement() const;

 23:            // Private - only member functions of this class

 24:            // can see the following members

 25:    private:

 26:      char name[30];

 27:      int  age;

 28:      int  retirementAge;

 29:  };

 30:

 31:int MoreNames();

 32:

 33:

 34:void main()

 35:  {

 36:    // Array to hold up to 20 people - initialized to 0 pointers

 37:    Person * people[20] = {0};

 38:    int more = 1;

 39:    int count = 0;

 40:

 41:    while (more)

 42:      {

 43:        more = MoreNames();  // Ask whether more input

 44:        if (more)

 45:         {

 46:           people[count] = new Person;

 47:           if (people[count]->AskForPerson())

 48:             count++;

 49:           else

 50:             {

 51:               cout << "** Invalid input - rejected **" << endl;

 52:               delete people[count]; // Tidy up problem

 53:             }

 54:         }

 55:       }

 56:

 57:     //

 58:     // Output collected data

 59:     //

 60:     cout << endl << endl

 61:          << "Name                           Age"

 62:          << "    Years to Retirement" << endl;

 63:

 64:     for (int i = 0; i < count; i++)

 65:       {

 66:         cout << people[i]->GetName();

 67:         for (int j = strlen(people[i]->GetName()); j < 31; j++)

 68:           cout << ' ';

 69:         cout << people[i]->GetAge();

 70:         if (people[i]->YearsToRetirement())

 71:           cout << "      " << people[i]->YearsToRetirement() << endl;

 72:         else

 73:           cout << "      " << "Retired" << endl;

 74:       }

 75:

 76:     for (i = 0;i < count; i++) // Tidy up dynamic data

 77:       delete people[i];

 78:  }

 79://************************************************************

 80://

 81:// Global functions

 82://

 83:

 84:int MoreNames()

 85:  {

 86:    char temp;

 87:    cout << endl << endl << "Do you want to add more names? ";

 88:    cin >> temp;

 89:    cin.ignore();

 90:    if (temp == 'y' || temp == 'Y')

 91:      return 1;

 92:    else

 93:      return 0;

 94:  }

 95://************************************************************

 96://

 97:// Person functions

 98://

 99:int Person::AskForPerson()

100:  {

101:    cout << endl << "Name: ";

102:    cin.getline(name,30);

103:    if (strlen(name) == 0)

104:      return 0;

105:    cout << "Age : ";

106:    cin >> age;

107:    cin.ignore();

108:    if (age < 0 || age > 120)

109:      return 0;

110:    cout << "Retirement age [0 for default]: ";

111:    cin >> retirementAge;

112:    if (retirementAge <= 0 || retirementAge > 120)

113:      retirementAge = 65;

114:    return 1;

115:  }

116:

117:const char * Person::GetName() const

118:  {

119:    return name;

120:  }

121:

122:int Person::GetAge() const

123:  {

124:    return age;

125:  }

126:

127:int Person::YearsToRetirement() const

128:  {

129:    if (age >= retirementAge)

130:      return 0;

131:    else

132:      return retirementAge - age;

133:  }

Output


Do you want to add more names? y

Name: Phill Dorrell

Age : 29

Retirement age [0 for default]: 0

Do you want to add more names? y

Name: Neil Hoskins

Age : 33

Retirement age [0 for default]: 0

Do you want to add more names? y

Name: Stefan Winman

Age : 28

Retirement age [0 for default]: 60

Do you want to add more names? y

Name: Trevor Cox

Age : 124

** Invalid input - rejected **

Do you want to add more names? n

Name                 Age    Years to Retirement

Phill Dorrell        29      36

Neil Hoskins         33      32

Stefan Winman        28      32

Analysis

The program is similar to the Contact program listed earlier. In this program, the class protects its own data. The class definition in lines 8 through 29 divides up its functions and members. The labels in lines 11 and 25 tell Visual C++ how to treat the following declarations. In this case, no outside function is allowed to see any of the data of class Person declared in lines 26 through 28 after the private label.

The main loop knows nothing about the class and how the data is held. Line 37 takes advantage of the initialization feature to initialize each element of the array to zero.

The class provides the functions GetName(), GetAge(), and YearsToRetirement() to allow nonmember functions to see the information. Because the return type is a copy of the data, the nonmember functions can't change the internal data. GetName() returns a const char *, which you'll recall was used for parameters to ensure that the data pointed to by a character pointer was not allowed to be changed.

The const after the parameter list of the functions for getting the data (for example line 117) does not mean that you can't change the returned data. Instead, it means that you are guaranteeing that the function will not change the data inside the class when the function executes. Visual C++ can't tell this for itself. This allows Visual C++ to let you call functions against data items that are constant:


const Person p;

p.AskForPerson(); // Invalid, updates Person

p.GetName();      // Valid, does not change Person

The storage of name in line 26 limits the class to a maximum of 29 characters for a name. In fact, there is no need for the limit. In AskForPerson() (lines 99 through 115) you could get the input into a temporary character string, dynamically allocate a string of the length to match the input, and hold a pointer to the string as a class member. Although you can do this to create the string and no external program needs to be aware of the change in the way the string is stored, you would need to introduce a function to tidy up the data, deleteing the character string before deleteing the Person structure. This is very important because without such a function, the application loses memory. The need to tidy up a class before it is deleted is a common and important problem—so important that we will look at it in the next unit.

The other problem with this class occurs if a new Person object is created, but the AskForPerson() function is not called. Following functions could go seriously wrong because the string and age data would not have been initialized. Because the data is private, there is no way that the main() function can initialize the data, and in any case the user of the class should not know how the data is held. This is another important hole to fill if you want to ensure that your classes are robust and error free.

The simple function in lines 127 through 133 shows how you can start to protect external functions from errors. For a start, line 132 knows how to calculate retirement ages. If Person was a simple structure, the user would have to remember that was the calculation. Furthermore, in line 129, the program ensures that it does not give negative numbers back to the calling function. In future revisions of the program, it might be useful to change the default logic of retirement ages to take into account different rules for different types of employees. Although some changes might be needed to get this information, other programs that just use the YearsToRetirement() function would not need to be changed to account for the new rules. This means that you've started to succeed in your objective of encapsulation, keeping all the code that is specific to the class hidden away inside member functions.

Homework



General Knowledge


  1. What sort of language is C++?

  2. Name (and spell!) the three important things that C++ provides, which other languages do not.

  3. How does encapsulation help stop programming errors?

  4. What buzzword is used to mean reusable code?

  5. What are functions belonging to a class called?

  6. How does Visual C++ know which class variable should be used by a member function?

  7. What label(s) can you use in a class declaration to stop external functions from accessing the data members of a class.

  8. What label(s) can you use in a class declaration to stop external functions from accessing the function members of a class?

  9. What label(s) can you use in a class declaration to stop member functions from accessing data members of a class?

  10. True or false: OOP is useful because it makes programs harder to understand and protects (encapsulates) programmers jobs.

  11. True or false: OOP programs run 10 times faster on average than other programs.

  12. True or false: Visual C++ programs are easier to maintain than standard C programs.

  13. True or false: The default access of a struct is public.

  14. True or false: The default access of a class is protected.

    What's the Output?


    Given the code

    
    class A
    
      {
    
        public:
    
          int a;
    
          int b;
    
          void Update(int a);
    
      };
    
    void main()
    
      {
    
        A a;
    
        a.Update(3);
    
        a.b = a.a;
    
        a.b++;
    
        int c = a.a;
    
      }
    
    void A::Update(int A)
    
      {
    
        a = A;
    
        b = 0;
    
      }

    what is the value of the following:

  15. Class member a at the end of the program?

  16. Class member b at the end of the program?

  17. main() variable a at the end of the program.

    Find the Bug


  18. Grizwald is having trouble with his code. Why won't his code compile?

    
    class A
    
      {
    
        int GetA();
    
        void SetA(int a);
    
        int a;
    
      };
    
    void main()
    
      {
    
        A a;
    
        a.SetA(5);
    
        int b = a.GetA();
    
      }
    
    int GetA()
    
      {
    
         return a;
    
      }
    
    void SetA(int A)
    
      {
    
        a = A;
    
      }

  19. What is wrong with this code snippet?

    
    class B
    
      {
    
        private:
    
          char b[30];
    
        public:
    
          void SetB(const char B);
    
      }
    
    void main()
    
      {
    
         B b;
    
         b.SetB("Hello there!");
    
      }

  20. Grizwald really isn't very good at this Visual C++ programming. He needs your help again to find another problem.

    
    class C
    
      {
    
        public:
    
          int a;
    
          void SetA(int a);
    
      };
    
    void main()
    
      {
    
        int a;
    
        SetA;
    
      }

    Write Code That. . .


  21. Change the code in PERSON.CPP in Listing 19.2 to dynamically allocate the name string. Use the strlen() function to determine how long the string is. Remember the comment about deleting the string at the end. For the time being, write a new member function called CleanUp(), which is called just before deleting a Person. Aside from adding the Cleanup() function, how many lines of code did you change that were not in the Person() class?

  22. Add code to PERSON.CPP to print a number alongside each entry. After displaying the listing, allow the user to enter the number to update the details of any entry. Add a new function to the class that allows the user to be shown the existing entry and decide whether it is to be changed. To keep input handling simple, allow the user to enter zero to indicate the age or retirement date is not to be changed.

    Extra Credit


  23. Write a program that allows you to enter the type, brand, and cost of each component of the PC that you are sitting in front of. The type should be entered as a code, and as the user enters the code, you should check that the code is valid. When the listing of the PC is displayed, you should show a description of the code.

Previous Page Page Top TOC Next Page