Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Advanced C 1992

.pdf
Скачиваний:
93
Добавлен:
17.08.2013
Размер:
4.28 Mб
Скачать

Part V •Appendixes

Listing C.5. continued

is “ <<

max(lValue1, lValue2, lValue3, lValue4) << “\n”;

cout << “Enter two floating point values: “;

cin >> dValue1 >> dValue2;

cout << “The max of “ << dValue1 << “ and “ << dValue2 << “ is “ << max(dValue1, dValue2) << “\n”;

}

double max( double a, double b, double c, double d)

{

if (a > b && a > c && a > d)

{

return (a);

}

if (b > a && b > c && b > d)

{

return (b);

}

if (c > a && c > b && c > d)

{

return (c);

}

return (d);

}

int

max(

int

a,

int

b,

int

c,

int

d)

{

 

if (a > b && a > c && a > d)

{

708

Introduction to C++

return (a);

}

if (b > a && b > c && b > d)

{

return (b);

}

if (c > a && c > b && c > d)

{

return (c);

}

return (d);

}

long

max(

long

a,

long

b,

long

c,

long

d)

{

 

if (a > b && a > c && a > d)

{

return (a);

}

if (b > a && b > c && b > d)

{

return (b);

}

if (c > a && c > b && c > d)

{

return (c);

}

return (d);

}

C C C

CCC

C C C

Notice this program incorporates function overloading as well. As shown, none of these C++ features are mutually exclusive. Any unused parameters default to the minimum value the data type can hold, which enables your maximum function to work correctly. That way, you’ll never select an unused argument as the maximum— nothing can be smaller than the default values.

709

Part V •Appendixes

References

In C, you can use a pointer to access a variable. Using a pointer allows a program to use a variable in two different ways, using different names. Pointers have their downside—they are often misunderstood, have the wrong value stored in them, and are awkward because you must try to remember whether you are dealing with a pointer, the object it is pointing to, or an object’s address.

C++ has a method that allows a variable to have more than one name. The second name isn’t a pointer (once defined, it can access only the variable by which it was defined), but is another way to access the variable’s storage.

EXAMP5.CPP, Listing C.6 is a program that shows the use of a reference variable in a C++ program.

Listing C.6. EXAMP5.CPP—Program showing a reference variable.

//Program EXAMP5.CPP, written 27 July 1992 by Peter D. Hipson

//Shows the use of reference variable, externally used as a

//function’s return value...

#include <iostream.h>

// function max() returns a reference variable...

int

max(int

a, int

b);

void main()

 

 

{

 

 

 

int

nValue1 = 0;

 

 

int

nValue2 = 0;

 

 

//Create a reference variable, which is not quite the same as a

//pointer to the original variable, because there is no actual

//pointer. A reference variable is more like a second name for

//a variable.

int

&nRef1 = nValue1;

cout << “Enter two integer values: “;

710

Introduction to C++

C C C

 

CCC

 

C

C

C

cin >> nValue1 >> nValue2;

cout << “The max of “ << nValue1 << “ and “ << nValue2 << “ is “ << max(nRef1, nValue2) << “\n”;

}

 

int

max(

int

a,

int

b)

{

 

if (a < b)

{

return (b);

}

else

{

return(a);

}

}

Notice in the cout statement

cout << “The max of “ << nValue1 << “ and “ << nValue2 << “ is “ << max(nRef1, nValue2) << “\n”;

that it refers to the variable nValue1 using the reference variable nRef1. The effect is the same as you would get by using the name nValue1.

References as Return Values

Using a reference variable as a return value creates an interesting situation. In this case, you can use the function’s name on the left side (as an lvalue) of an assignment operator.

The EXAMP6.CPP program in Listing C.7 shows the effect of using a reference variable as a return value.

711

Part V •Appendixes

Listing C.7. EXAMP6.CPP—Program showing a reference variable.

//Program EXAMP6.CPP, written 27 July 1992 by Peter D. Hipson

//Shows the use of reference variable, externally used as a

//function’s return value...

#include <iostream.h>

// Defined is an int max() function.

int

nLimit = 0;

// function max() returns a reference variable...

int

&max(int

a, int

b);

void main()

 

 

{

 

 

 

int

nValue1 = 0;

 

 

int

nValue2 = 0;

 

 

//Create a reference variable, which is not quite the same as a

//pointer to the original variable, because there is no actual

//pointer. A reference variable is more like a second name for

//a variable.

int

&nRef1 = nValue1;

cout << “Enter two integer values: “;

cin >> nValue1 >> nValue2;

cout << “The max of “ << nValue1 << “ and “ << nValue2 << “ is “ << max(nRef1, nValue2) << “\n”;

cout << “The value of nLimit is “ << nLimit << “\n”;

max(0, 0) = 99;

cout << “The value of nLimit is “ << nLimit << “\n”;

712

Introduction to C++

C C C

 

CCC

 

C

C

C

}

 

int

& max(

int

a,

int

b)

{

 

if (a < b)

{

nLimit = b; return (nLimit);

}

else

{

nLimit = a; return(nLimit);

}

}

To better understand the effects of running this program, take a look at its output, shown in Figure C.2.

Figure C.2. Output from EXAMP6.CPP.

713

Part V •Appendixes

Notice after the statement

max(0, 0) = 99;

was executed the value of nLimit changed to 99. Only your creativity limits how you use this ability of C++.

Classes

Classes are one of the most important elements of C++. They enable you to use one of the most powerful features of the language—data object management. You might think of classes as an extension to C’s user-defined types. In C, when defining a type (using typedef), you can include only actual data objects in that type. No checking takes place to find if correct values have been assigned to a C user-defined type.

Using C++ classes gives you many advantages. These advantages, described in the following section, are valuable in maintaining your application’s data integrity.

A class can have all the allowed data types within it, including other classes. Nesting classes is done much the same as you would nest typedef’d objects in C.

A class has a constructor, a function called whenever a data object of that class is created. You may have more than one constructor, each of which must have a different number of parameters. The constructor is responsible for ensuring that each member of the class is properly initialized and that any initialization values passed to the constructor are valid.

A class has a number of manipulation functions that you can use to store values in the class’s members, retrieve member values, print, output, input, or otherwise manipulate its members.

A class also has a destructor, a function called whenever the class object is about to be destroyed. This function can take care of housekeeping, such as freeing any allocated memory.

Using a class requires you to determine, as well as you possibly can, what you will use for members in the class. You never have a problem adding members as needed or writing class functions to access new members; however, planning ahead helps prevent unchecked changes that can cause problems.

714

Introduction to C++

C C C

 

CCC

 

C

C

C

Listing C.8, EXAMP7.CPP, is a program that creates a class based on the database example program CREATEDB.C in Chapter 7, “C Structures.” The CREATEDB.C program makes a database record for either a customer or a supplier.

Listing C.8. EXAMP7.CPP—Program showing C++ classes.

//Program EXAMP7.CPP, written 27 July 1992 by Peter D. Hipson

//Shows C++ classes, initialization, and so on.

#include

<string.h>

//

Used for strcpy(), str...(), etc.

#include

<iostream.h>

//

C++’s stream I/O header.

//Define your class structure, similar to those

//created in earlier chapters showing database techniques.

#define CUSTOMER_RECORD 1 #define SUPPLIER_RECORD 2

/* Define your structure for the customer database. */

class Customer

 

{

 

 

public:

 

 

Customer();

// The default constructor

Customer(int nRecType,

// The class constructor

 

char * szCustName,

 

 

char * szAddr,

 

 

double dSales);

 

void GetCustomer();

 

void PrintCustomer();

// Print a customer’s information

~Customer();

// Destructor

private:

 

 

int

nRecordType;

 

char

szCustomerName[120];

char

szAddress[120];

 

double dCurrentSales;

continues

715

Part V •Appendixes

Listing C.8. continued

};

Customer::Customer() // The class constructor, default values.

{

nRecordType = CUSTOMER_RECORD; strcpy(szCustomerName, “-NONE-”); strcpy(szAddress, “-NONE”); dCurrentSales = 0.0;

}

 

Customer::Customer(int nRecType,

// The class constructor, explicit

 

// values

char * szCustName,

 

char * szAddr,

 

double dSales)

 

{

 

nRecordType = nRecType; strcpy(szCustomerName, szCustName); strcpy(szAddress, szAddr); dCurrentSales = dSales;

}

void Customer::GetCustomer()

{

char szLine[2]; // Used to store a NEWLINE for cin.getline

//You get, from the console, the object’s data values, using a simple

//multiline format:

cout << “Enter ‘“ << CUSTOMER_RECORD << “‘ for a Customer ‘“ << SUPPLIER_RECORD << “‘ for a supplier: “;

cin >> nRecordType;

//Below you don’t use cin, but cin.getline, which gets all

//characters until the delimiting character (the optional third

//character). If the delimiting character is omitted, a

//newline is assumed. When getting input, cin.getline() does not

//retrieve more characters than the second parameter specifies,

//taking into consideration the ending NULL for the string.

716

Introduction to C++

C C C

 

CCC

 

C

C

C

cin.getline(szLine, sizeof(szLine)); // discard NEWLINE from last // input.

cout << “Enter the name: “; cin.getline(szCustomerName, sizeof(szCustomerName));

cout << “Enter the address: “; cin.getline(szAddress, sizeof(szAddress));

cout << “Enter the sales: “; cin >> dCurrentSales;

}

void Customer::PrintCustomer()

{

//You print the object’s data values, using a simple

//multiline format:

cout << “Type\t” << nRecordType << “\n” << “Name\t” << szCustomerName << “\n” << “Address\t” << szAddress << “\n” << “Sales:\t” << dCurrentSales << “\n”;

}

Customer::~Customer()

{

//Nothing done here. You don’t have anything to do when the

//object is destroyed.

}

void main()

{

//The first object is initialized with the default values. Customer Customer1;

//The second object is initialized with explicit values.

Customer Customer2(CUSTOMER_RECORD, “John Smith”, “New York, NY 10000”,

1234.5);

continues

717