Previous Table of Contents Next


The ability to define variables extends to the struct and union keywords. In C++, as soon as you declare a structure Mystruct, you can use It to declare variables:
Mystruct a, b, c, d;
In C, you would have to use the struct keyword:
struct Mystruct a, b, c, d;
Alternatively, you could use a typedef declaration to skip this step. In either case, C requires extra work. For the sake of compatibility with C, C++ supports this same use of struct and typedef. But once you start using C++, you can adopt the practice of declaring variables directly.

Once we have declared the strings, what do we call them? What are the entities a, b, c, and d in the following declaration?

CStr a, b, c, d;

These variables are all objects. If you have been listening to the dogma of object orientation, this may be an exciting moment for you: you finally have objects! To some people, the appearance of objects may seem deserving of a Nobel prize. (“Now that I have objects in my program, I’m going to save the world!”)

Before you go out and celebrate, you should realize that you’ve been using objects all along. Technically speaking, an object in C++ is just a variable or other piece of data. Yet the term object does communicate something meaningful. An object is something that, through its class declaration, may be given behavior. C has variables but doesn’t really have objects in the sense that C++ has them.

Calling a Member Function

Without further ado, let’s look at behavior in the string objects. These objects know how to respond to the get, getlength, cpy, and cat functions:

CStr string1, string2;

string1.cpy(“My name is ”);   // Copy string to string1
string2.cpy(“Bill.”);         // Copy string to string2
string1.cat(string2.get());             // Concat string2 onto
                                        // string1
puts(string1.get());                    // Get string1 data and
                                        // print

Each of the last four lines involves a call to a member function. Note the use of the dot (.) in a function call:

object.member_function(arguments)

If you’ve used structures in C, this syntax should look familiar. It’s a natural extension of the syntax used to refer to a structure member:

object.member

Let’s look more closely at one of these function calls. This first function call gives a command to the string1 object, in effect saying, “Copy the given string to yourself.”

string1.cpy(“My name is ”); // Copy string to string1

This function call tells string1 to copy the data “My name is ” to itself. The string1 object knows how to copy other strings this way because it has a built-in cpy function. Poetically, we can say that cpy is part of the object’s behavior.

In actuality, here’s what happens. The compiler recognizes string1.cpy( ) as a function call. It knows that string1 is an object of the class CStr. The function call is therefore resolved as a call to CStr::cpy.


Figure 5.2  Resolving calls to member functions.

Earlier in the program, string1 and string2 were defined as objects of class CStr. So calls to string2.cpy( ) also result in calls to CStr::cpy. Objects of the same class share all their function code and in this sense have the same behavior.

What happens in the CStr::cpy function call? Control passes to the CStr::cpy function, just as it would with any normal function call.


Figure 5.3  Member function access to data members

But something interesting is going on here, as Figure 5.3 shows: the variable sData is a CStr data member. This data member belongs to the object string1.

Each object of class CStr has its own copy of the data member, sData. In this example, the statement calls CStr::cpy through the string object, string1. Therefore, when the function refers to sData, it is string1’s copy of sData that is referenced. Figure 5.3 illustrates this connection.

Code and data work differently in objects. The following rules hold true regardless of what’s public and what’s private:

  Objects of the same class share function code. You resolve a call to a member function by determining the object’s class and then calling class::member_function.
  But each individual object has its own copy of the data members.

One way to understand the distinction between code and data is to remember that objects are just packets of data. If you’ve worked with structures in C, records in Pascal, or user-defined types in Basic, the fact that C++ objects have data members is nothing new. And because these packets are collections of variables, they can vary from one another. Each C++ object can assign different values to its data members, so each object must have its own copy of these members.

Member functions are what’s new. But member functions are just functions restricted to working on data of a particular type (i.e., a particular class). A member function works equally well on any object in its class. Functions, therefore, exist at the class level.

Figure 5.4 illustrates the class/object relationship and how it involves code and data. Assume that you define four string objects: str1, str2, str3, and str4.

CStr str1, str2, str3, str4;

Each of these objects shares code created for the CStr class while also having its own copy of the CStr data member, sData.


Figure 5.4  Code and data in the CStr class.

In this case, there is only one data member, but most classes have more than one. For example, we might create a class CTemp_point, which locates a point in three-dimensional space and a temperature value:

class CTemp_point {
   int     x, y, z;
   double temp;
public:
   void set_point(int x, y, z);
   void get_point(int *x, *y, *z);
   void set_temp(double new_temp);
   double get_temp(void);
};

Assume, also, that you define four objects of this class:

CTemp_point pntA, pntB, pntC, pntD;

Here, all the instances of this class—that is, the individual points—share the CTemp_point function code in common, just as string objects share the CStr function code. But each point has its own copy of the four data members: x, y, z, and temp. (See Figure 5.5).


Figure 5.5  Code and data in the CTemp_point class.

Member Functions: A Walk-Through

If its clear to you how member functions work, you can skip to the next section. This section gives you an additional perspective on the working of member functions by walking through a series of function calls. Consider this code:

CStr string1, string2;

string1.cpy(“My name is ”);  // Calls CStr::cpy
string2.cpy(“Bill.”);        // Calls CStr::cpy
string1.cat(string2.get());  // Calls CStr::cat and
                             // CStr::get
puts(string1.get());         // Calls CStr::get


Previous Table of Contents Next