C++ Redux
Volume Number: 10
Issue Number: 1
Column Tag: Getting Started
Related Info: Color Quickdraw
C++ Redux
Rehashing the basics
By Dave Mark, MacTech Magazine Regular Contributing Author
Note: Source code files accompanying article are located on MacTech CD-ROM or
source code disks.
Back in the October ‘93 Getting Started column, we took a look at the basics of
object programming using C++. Since the column came out, I’ve gotten tons of
feedback, from both C++ novices and experts alike. After sorting through all the
comments, I took a few days and did a complete rewrite of the October column and of the
corresponding chapter (Chapter 5) in Learn C++ on the Macintosh. If you’ve read the
first printing of Learn C++ on the Macintosh (the changes will appear in the second
printing) or made your way through the first edition of this column, please take the
time to read this new version. As a bonus, this month’s column includes a C++
program that demonstrates the techniques described throughout the text (the October
column didn’t include a program).
Objects
There is nothing mysterious about the concept of an object. In C++, an object is
any instance of a data type. For example, this line of code:
int myInt;
declares an int object. This column will teach you how to use C++ to create,
destroy and manipulate objects in very powerful ways.
The first object we’ll take a look at is the structure.
The Organizational Power of the Struct
One of the most valuable features shared by C and C++ is the structure. Without
the structure, you’d have no way to group data that belonged together. For example,
suppose you wanted to implement an employee data base that tracked an employee’s
name, employee ID, and salary. You might design a structure that looks like this:
const short kMaxNameSize = 20;
struct Employee
{
char name[ kMaxNameSize ];
long id;
float salary;
};
The great advantage of this structure is that it lets you bundle several pieces of
information together under a single name. This concept is known as encapsulation.
For example, if you wrote a routine to print an employee’s data, you could write:
Employee newHire;
PrintEmployee( newHire.name, newHire.id, newHire.salary );
Did you notice anything unusual about the declaration of newHire in the preceding
code sample? In C, this code would not have compiled. Instead, the declaration would
have looked like this:
struct Employee newHire; /* The C version */
When the C++ compiler sees a structure declaration, it uses the structure name
to create a new data type, making it available for future structure declarations.
On the other hand, it would be so much more convenient to pass the data in its
encapsulated form:
PrintEmployee( &newHire );
Encapsulation allows you to represent complex information in a more natural,
easily accessible form. In the C language, the struct is the most sophisticated
encapsulation mechanism available. As you'll soon see, C++ takes encapsulation to a
new level.
Encapsulating Data and Functions
While C structures are limited strictly to data, C++ supports structures
composed of both data and functions.
Here's an example of a C++ structure declaration:
const short kMaxNameSize = 20;
struct Employee
{
// Data members...
char employeeName[ kMaxNameSize ];
long employeeID;
float employeeSalary;
// Member functions...
void PrintEmployee();
};
This example declares a new type named Employee. You can use the Employee type
to declare individual Employee objects. Each Employee object is said to be a member of
the Employee class.
The Employee class consists of three data fields as well as a function named
PrintEmployee(). In C++, a classes’ data fields are known as data members and its
functions are known as member functions.
Each Employee object you create gets its own copy of the Employee class data
members. All Employee objects share a single set of Employee member functions.
Later in the column, you’ll see how to access an object’s data members and
member functions. For now, let’s take a look at the mechanisms C++ provides to create
and destroy objects.
Creating an Object
There are two ways to create a new object. The simplest method is to define the
object directly, just as you would a local variable:
Employee employee1;
This definition creates an Employee object whose name is employee1. employee1
consists of a block of memory large enough to accomodate each of the three Employee
data members.
When you create an object by defining it directly, as we did above, memory for
the object is allocated when the definition moves into scope. That same memory is freed
up when the object drops out of scope.
For example, you might define an object at the beginning of a function:
void CreateEmployee()
{
Employee employee1;