Tải bản đầy đủ (.pdf) (10 trang)

A Complete Guide to Programming in C++ part 34 doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (180.65 KB, 10 trang )

ENUMERATION

309
ᮀ Definition
An enumeration is a user-definable, integral type. An enumeration is defined using the
enum keyword. A range of values and a name for these values are also defined at the
same time.
Example: enum Shape{ Line, Rectangle, Ellipse};
This statement defines the enumerated type Shape. The names quoted in the list iden-
tify integral constants. Their values can be deduced from the list order. The first constant
has a value of 0, and each subsequent constant has a value that is one higher than its
predecessor.
In the previous example,
Line thus represents a value of 0, Rectangle a value of 1,
and Ellipse a value of 2. A Shape type variable can only assume one of these values.
Example: Shape shape = Rectangle; // Variable shape
//
switch(shape) // To evaluate shape
{
case Line: // etc.
However, you can also define the values of the constants explicitly.
Example: enum Bound { Lower = -100, Upper = 100};
You can leave out the type name, if you only need to define the constants.
Example: enum { OFF, OUT=0, ON, IN=1 };
This statement defines the constants OFF and OUT, setting their value to 0, and the con-
stants ON and IN with a value of 1. The values for OFF and ON are implicit.
ᮀ Class-Specific Constants
Enumeration can be used to define integral symbolic constants in a simple way. In con-
trast to #define directives, which merely replace text strings, enum constants are part
of a declaration and thus have a valid range. This allows you to define constants that are
visible within a namespace or class only.


The example on the opposite page shows the enumerated type State, which was
defined within the Lights class. This means that the type and enum constant are only
available for direct use within the class. The enumeration itself is declared as public,
however, and access from outside the class is therefore possible.
Example: if(Lights.getState() == Lights::red)
//
exercises
310

CHAPTER 15 MEMBER OBJECTS AND STATIC MEMBERS
Article( const Article& );

EXERCISES
Copy constructor of class Article
The copy constructor creates a copy of an existing object.The parameter is thus
a read-only reference to the object that needs to be copied.The copy
constructor in the
Article class is thus declared as follows:
Declaration of copy constructor:
The default copy constructor simply transfers the data members to the new
object.
The Member Class
int
string
const Date
Member Number
Name
Birthday
//Possibly more information, such as an address, telephone number,
Constructor with one parameter for each data member

Access methods for each data member. The birthday is read-only.
A method for formatted screen output of all data members
Private Data Members
Public Methods
Type
EXERCISES

311
Exercise 1
In the first exercise of the last chapter you defined a simple class called
Article.This involved using a global counter to log object creation and
destruction. Improve and extend the
Article class as follows:
■ Use a static data member instead of a global variable to count the current
number of objects.
■ Declare a static access method called getCount()for the Article class.
The method returns the current number of objects.
■ Define a copy constructor that also increments the object counter by 1
and issues a message.This ensures that the counter will always be accu-
rate.
Tip: Use member initializers.
■ Test the new version of the class.To do so, call the function test() by
passing an article type object to the function.
Exercise 2
A sports club needs a program to manage its members.Your task is to define
and test a class called
Member for this purpose.
■ Define the Member class using the data members shown opposite. Use
the
Date class defined in the last chapter for your definition. Since a

member’s birthday will not change, the data member for birthdays must
be defined as a
const.
Overload the constructor to allow for entering a date as an object as
well as three values for day, month, and year.
■ Implement the necessary methods.
■ Test the new Member class by creating at least two objects with the data
of your choice and calling the methods you defined.
■ Add a static member called ptrBoss to the class.This pointer indicates
the member who has been appointed as chairperson. If no chairperson
has been appointed, the pointer should point to
NULL.
■ Additionally, define the static access methods getBoss() and setBoss().
Use a pointer to set and return the object in question.
■ Test the enhanced Member class by reading the number of an existing
member, making the member the new chairperson and displaying the
chairperson using
getBoss().
312

CHAPTER 15 MEMBER OBJECTS AND STATIC MEMBERS
Simulation of two traffic lights!
Terminate this program with <Ctrl>+<C>!
1. Light 2. Light

RED AMBER
GREEN
AMBER
AMBER RED
GREEN

AMBER
RED AMBER
GREEN
// . . .
Sample output
Hints for implementing the function wait()
1. The function time() is declared in the header file ctime. The call
time(NULL) determines the number of seconds of type time_t since
1.1.1970, 0:0 hours.The type
time_t is defined as long.
2. Instead of calling the function
time() in a loop, you can use the function
Sleep() for Windows or the function sleep() for Unix. These system
calls are not standardized, yet they are much more effective because they
send a process to sleep instead of using a waiting loop.
EXERCISES

313
Exercise 3
Create a program to simulate the signal positions for two sets of traffic lights at
a junction. Use the class
Lights as defined in this chapter for your program.
■ Each set of lights is switched through the phases red, amber, green, amber,
red, and so on.You must ensure that one set of lights can be only in the
amber or green state when the other set of lights is red.
■ The lights operate in an infinite loop that can be terminated by interrupt-
ing the program.You can use the key combination <Ctrl>+<C> for DOS
and Windows and the Interrupt key, i.e., normally the <Del> key, for
UNIX.
■ The status of the lights is constant for a certain number of seconds. For

example, the green phase can take 20 seconds and the amber phase 1
second.These values can be different for each set of lights. Define an
auxiliary function
inline void wait( int sec)
The function returns after the stipulated number of seconds.To do so,
you can call the standard function
time() in a loop. Don’t forget to read
the notes on the opposite page.
solutions
314

CHAPTER 15 MEMBER OBJECTS AND STATIC MEMBERS

SOLUTIONS
Exercise 1
//
// article.h
// Defines a simple class - Article.
//
#ifndef _ARTICLE_H_
#define _ARTICLE_H_
#include <string>
using namespace std;
class Article
{
private:
long nr; // Article number
string name; // Article name
double sp; // Sales price
// Static data member:

static int countObj; // Number of objects
public:
Article( long nr=0, const string& name="noname",
double sp=0.0);
// Copy constructor:
Article( const Article& anArticle);
~Article();
void print();
// Access methods:
const string& getName() const { return name; }
long getNr() const { return nr; }
double getSP() const { return sp; }
static int getCount() { return countObj; }
bool setName( const string& s)
{
if( s.size() < 1) // No empty Name
return false;
name = s;
return true;
}
void setNr( long n) { nr = n; }
void setSP(double v)
{ // No negative price
sp = v > 0.0 ? v : 0.0;
}
};
#endif // _ARTICLE_
SOLUTIONS

315

//
// article.cpp
// Methods of Article, which are not defined as inline.
// Constructor and destructor output when called.
//
#include "article.h" // Definition of the class
#include <iostream>
#include <iomanip>
using namespace std;
// Defining the static data member:
int Article::countObj = 0; // Number of objects
// Defining the constructor and destructor:
Article::Article( long nr, const string& name, double sp)
{
setNr(nr); setName(name); setSP(sp);
++countObj;
cout << "An article \"" << name
<< "\" is created.\n"
<< "This is the " << countObj << ". article!"
<< endl;
}
// Defining the copy constructor:
Article::Article( const Article& art)
:nr(art.nr), name(art.name), sp(art.sp)
{
++countObj;
cout << "A copy of the article \"" << name
<< "\" is generated.\n"
<< "This is the " << countObj << ". article!"
<< endl;

}
Article::~Article()
{
cout << "The article \"" << name
<< "\" is destroyed.\n"
<< "There are still " << countObj << " articles!"
<< endl;
}
// The method print() outputs an article.
void Article::print()
{
// As before! Compare to the solutions of chapter 14.
}
316

CHAPTER 15 MEMBER OBJECTS AND STATIC MEMBERS
//
// article_t.cpp
// Tests the class Article including a copy constructor.
//
#include "article.h" // Definition of the class
#include <iostream>
#include <string>
using namespace std;
void test( Article a); // Prototype
Article article1( 1111,"tent", 159.9); // Global
int main()
{
cout << "\nThe first statement in main().\n" << endl;
Article article2( 2222,"jogging shoes", 199.99);

cout << "\nThe first call of test()." << endl;
test(article1); // Passing by Value
cout << "\nThe second call of test()." << endl;
test(article2); // Passing by Value
cout << "\nThe last statement in main().\n"
<< "\nThere are still " << Article::getCount()
<< " objects\n" << endl;
return 0;
}
void test( Article a) // Calls the copy constructor
{
cout << "\nThe given object:" << endl;
a.print();
static Article bike( 3333, "bicycle", 999.0);
cout << "\nThe static object in function test():"
<< endl;
bike.print();
cout << "\nThe last statement in function test()"
<< endl;
}
SOLUTIONS

317
Exercise 2
The Date class from the last chapter ( see files Date.h and Date.cpp ) can be
left unchanged. But it makes sense to define the function
isLeapYear()as a
static member function of class
Date rather than globally.
The other files:

//
// member.h
// Defines the Member class containing a constant
// and a static member.
//
#ifndef _MEMBER_H_
#define _MEMBER_H_
#include "Date.h"
#include <string>
using namespace std;
class Member
{
private:
int nr; // Member number
string name; // Name
const Date birth; // Birthday
// more data
static Member *ptrBoss; // Pointer to boss,
// NULL = no boss.
public:
Member( long m_nr, const string& m_name,
const Date& m_birth)
: nr(m_nr), birth(m_birth)
{
if( !setName(m_name)) name = "Unknown";
}
Member( long m_nr, const string& m_name,
int day, int month, int year)
: nr(m_nr), birth(day,month,year)
{

if( !setName(m_name)) name = "Unknown";
}
int getNr() const { return nr; }
const string& getName() const { return name; }
const Date& getBirthday() const { return birth; }
void setNr( int n) { nr = n; }
318

CHAPTER 15 MEMBER OBJECTS AND STATIC MEMBERS
bool setName( const string& s)
{
if( s.size() < 1) // No empty name
return false;
name = s;
return true;
}
void display() const;
// static methods:
static Member* getBoss()
{
return ptrBoss;
}
static void setBoss( Member* ptrMem)
{
ptrBoss = ptrMem;
}
};
#endif // _MEMBER_H_
//
// member.cpp

// Members of class Member not defined inline.
//
#include "member.h" // Class definition
#include <iostream>
using namespace std;
// Pointer to the boss:
Member* Member::ptrBoss = NULL;
void Member::display() const
{
string line( 50, '-');
cout << line
<< "\n Member number: " << nr
<< "\n Member: " << name
<< "\n Birthday " << birth.asString()
<< '\n' << line << endl;
}

×