User-defined Data Types

In C++, a user-defined variable is called an object. Each object has a type, just like variables of native types (short, char, etc.). For example, if we define a class called StockItem (as we will do in this chapter), then an object can be of type StockItem, just as a native variable can be of type short. However, an additional step is required when we want to use user-defined types. Since the compiler has no intrinsic knowledge of these types, we have to tell it exactly what they are and how they work. We do this by defining a class, which specifies both the data contained in the user-defined variable and what operations can be performed on these data.

Here's how Susan reacted upon her first encounter with this idea.

Susan: I can tell that there is only one thing that I think that I understand about this. That is, that C++ is not a language. You have to make it up as you go along. . . .

That may be overdoing it a bit, but there is a grain of truth in her observation: C++ is more of a "language kit" than it is a language. What do I mean by this?

I mean that to use C++ in the most effective way, rather than merely as a "better C", it is necessary to create data types and tell the compiler how to treat them as though they were native data types. So far in this book, we have been using data types that were previously defined, either by the compiler and language (native types, e.g., short, char) or by libraries (class types, e.g., string). Now we're going to actually make up our own types that will be usable just like native types. The difference between using variables and making up new variable types is analogous to the difference between using a program and writing a program, but carried to the next higher level.

In the event that you find this notion hard to understand, you're not alone; so did Susan.

Susan: This is an outrage! I didn't understand one other word after this as I was far beyond anything that could even be described as shock. I think I did faint. I may as well have been in a coma.

Interestingly enough, she actually did understand this idea of making up our own data types, so perhaps she was overestimating the degree of her shock.

Before we get back to the technical explanation of how we create new data types, I'm sure one more question is burning in your mind: Why should we do this? What's wrong with the native types like char and short? The answer is simple: we make up types so that we can match the language to the needs of the problem we're trying to solve. For example, suppose we want to write a program to do inventory control for a small business like a grocery store. Such a program needs objects representing items in the store, which have prices, names, and so on. We need to define each of these types of objects so that it can display the behavior appropriate to the thing it represents. The availability of objects that have relevance to the problem being solved makes it much easier to write (and read) a program to handle inventory than if everything has to be made of shorts and chars.

I suspect that the advantages of making up one's own data types may still not be apparent to you, so let me make an analogy with natural languages. Making up new data types in C++ is in some ways quite similar to making up new words in English (for example). You might think that if everyone made up new words, the result would be chaos. Actually, this is correct, with the very important exception of technical jargon and other vocabularies that are shared by people who have more in common than simply being speakers of English. For example, physicians have their own "language" in the form of medical terminology. Of course, a cynical observer might conclude that the reason for such specialized vocabulary is to befuddle or impress the naive listener, and of course it can be used for that purpose. However, there is also a much more significant and valid reason for using technical jargon: to make it possible for experts in a field to communicate with one another quickly and precisely. The same is true of creating our own data types; they enable us to write programs that are more understandable to those who are conversant with the problems being solved. It's much easier to talk to a store owner about inventory objects than about shorts and chars!

Here's the discussion that Susan and I had on this topic:

Susan: Why should we have user-defined data types?

Steve: So that you can match the language to the needs of the problem you're trying to solve. For example, if you were writing a nurse's station program in C++, you would want to have objects that represented nurses, doctors, patients, various sorts of equipment, and so on. Each of these objects would display the behavior appropriate to the thing or person it was representing.

Susan: Why do you need that? What if each individual who spoke English made up a unique version of English (well, it is user-defined, right?), how could we communicate? This is garbage.

Steve: We need user-defined types for the same reason that specialists need jargon in their technical fields. For example, why do you health-care professionals need words like tachycardia? Why don't you just say "a fast heartbeat" in simple English?

Hey, that's not a bad way to explain this: Adding classes is like adding specialized vocabulary to English. I don't remember ever seeing that explanation before; what do you think of it?

Susan: Huh? Then you are saying that, by defining a class of objects, they can take on more realistic qualities than just abstract notions? That is, if I wanted to represent nurses in a program, then I would do it with a class named nurse and then I can define in that program the activities and functions that the nurse objects would be doing. Is this how you keep everything straight, and not mix them up with other objects?

Steve: Yes, that's one of the main benefits of object-oriented programming. You might be surprised how hard it is to teach an old-line C programmer the importance of this point.

Susan: So is this what object-oriented programming is? I have heard of it, but never knew what it meant. Could it also be described as user-defined programming? I guess there are advantages to teaching a novice; you don't have to undo old ideas to make way for newer ones. So, anything that is user-defined is a class? That is, native variables are not classes?

Steve: Right. Every user-defined type is a class; data items of a class type are called objects. Variables of native types are not objects in the object-oriented sense.

Susan: OK, so if I want to make up something, then what I make up is called a class as opposed to the other type of stuff that isn't made up and is really part of C++; that is called native. That is intuitive, thank you. Then the class is made up of data items? And what about native variables; are they objects? I guess just the variables of the class are called objects because I just read your definition for object. So native variables are not objects, they are just variables. Am I am talking in circles again?

Steve: No, you're not; you're making perfect sense. The only point you have missed is that there are functions in the objects, as well as data items. We'll get into that shortly.

Susan: So Steve, tell me: What have I been doing up to this point? How does this new stuff compare to the old stuff and which one is it that the programmer really uses? (Let's see, do I want curtain 1 or 3; which one holds the prize?) I just want to get a little sense of direction here; I don't think that is a whole lot to ask, do you?

Steve: What you've been doing up to this point is using classes (string, Vec) as well as native types like short and char. This new stuff shows how to create classes like string, rather than just using them.[6]

[6] In case you were wondering, you can't create new native types.

Assuming that I've sold you on the advantages of making up our own data types, let's see how we can actually do it. Each data type is represented by a class, whose full definition is composed of two parts: the interface definition (usually contained in a file with the extension .h), and the implementation definition (usually contained in a file with the extension .cpp). The interface definition tells the compiler (and the class user) what the class does, while the implementation definition tells the compiler how the objects of that class actually perform the functions specified in the interface definition. Let's take a look at a step-by-step description of how to create and use a class.

1.
Write the class interface definition, which will be stored in a file with the extension .h. In our example of a StockItem class, we'll use item1.h to hold our first version of this interface definition. This definition tells the compiler the names and types of the member functions and member variables that make up the objects of the class, which gives the compiler enough information to create objects of this class in a user's program.

2.
Write the class implementation definition, which will be stored in a file with the extension .cpp; in our example, the first one of these will be stored in the file item1.cpp. This definition is the code that tells the compiler how to perform the operations that the interface definition refers to. The implementation definition file must #include the interface definition file (item1.h, in this case) so that the compiler has access to the interface that is being implemented. It needs this information to check that the implementation is proper (i.e., that it conforms to the interface specified in the interface definition file).

3.
Write the program that uses objects in the class to do some work. The first such program we'll write will be itemtst1.cpp. This program also needs to #include the interface definition file, so that the compiler can tell how to create objects of this class.

4.
Compile the class implementation definition to produce an object file (item1.o). This makes the class available to the user program.

5.
Compile the user program to produce an object file (itemtst1.o).

6.
Link the object file from the user program, the object file from the class implementation definition, and any necessary libraries together to form a finished executable. Our first sample will be called itemtst1.exe.

A couple of items in this list need some more discussion. Let's see how Susan brought them to my attention.

Susan: I have a problem here. First under item 2, you put "The class implementation definition file must #include"; excuse me, but that doesn't make sense. What do you mean by #include? How do you say that, "pound include"?

Steve: Yes, that's how it's pronounced. You could also leave off the "pound" and just say "include", and every C and C++ programmer would understand you. As you may recall, a #include statement causes the compiler to pretend that the code in the included file was typed in instead of the #include statement.

Susan: Section 6 that stuff with the linking. . .isn't that done by the compiler; if not, how do you do it?

Steve: The linker does it, but the compiler is generally capable of calling the linker automatically for you; that's why we haven't needed to worry about this before.

Susan: OK, where is the linker? Is it not part of the compiler software? If not, where does it come from?

Steve: Every compiler comes with one, but you can also buy one separately if you prefer.

Susan: Who puts it in your computer? Also, how do you "call" the linker if you have always had the compiler do it for you?

Steve: It is installed along with the compiler. You can tell the compiler not to call it automatically if you prefer to do it manually; there are reasons to do that sometimes. For example, when you're making a change that affects only one module in a large program, you can recompile only that one module, then relink all the object files again to make the executable.

Susan: How do you do that?

Steve: It varies according to what compiler you're using. With the compiler on the CD in the back of the book, you specify source files and object files in the command line that you use to run the compiler. The compiler will compile the source files and then link them with the object files.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset