Deep C++

Get Real: Using Objects in Real-World Programming

By Brian Overland

"What is the nature of the real world?" asked the student.
"I don’t know," said the professor, "I’ve never been there."

— Anonymous graffiti artist

By now you’ve heard it all. Objects will save the world. (Yes, but how?) To be a real programmer these days, you’ve got to learn the C++ language. (Yes, but why?) Object orientation will solve all your problems. (Really? When?) You may be exasperated with the hoopla, wondering if object orientation is just an academic pet theory. Do I really need object orientation, and what has it got to do with real programming problems?

The truth is that C++ is a significant tool for helping you solve certain kinds of problems. It does not solve problems for you,, nor does it even express solutions you couldn’t somehow express in C. But for certain real-world problems, such as developing a graphical user interface, C++more naturally expresses what you want the program to do. The C++ versions of such programs are more concise, more readable, and less error-prone than their C counterparts.

Languages, after all, are tools for expressing ideas. In theory, you can express everything in English that you can in another human language, but some languages do express certain ideas more easily than others. This is why writers in English sometimes borrow from French, for example, to acquire that touch of je ne sais quoi.

In fact, the versatility and expressiveness of English is due precisely to the fact that it has stolen so much from other languages. The same relationship exists between C++ and C: C++ can express everything that C can, and then some.

How the Hype Originated

The only PR problem object orientation has ever really had is one of overly high expectations. The history of programming languages is one of dramatic evolution in programming tools, progressing from machine language to object-oriented tools such as C++ and Visual Basic. But the most dramatic progress occurred in the early generations of languages. Later generations have gradually introduced more subtle refinements—a fact people have lost sight of.

Imagine the first computer programmers, who had to write in machine language. This involved hand-assembly, a tedious process of looking up the binary code for each instruction. It wasn’t long before people figured out that this was exactly the sort of job the computer could do And so assembly language was born.

An assembly-language program is made up of at least somewhat recognizable words. For example, the following assembly program is vastly preferable to a jumble of hex code:

   .DATA
   str DB "Hello, world!"
   .CODE
   PUSH str
   CALL print

High-level languages represented another major improvement, although not as dramatic as the first. Now these semi-comprehensible lines of assembly code could be replaced by an even easier to understand expression (as in BASICA):

   PRINT "Hello, world!"

From there we move to structured languages, which introduce superior ways of organizing code. But a structured language does nothing to make a one-line program easier to write or understand. You probably need to write at least a 20- or 30-line program, in which you can make use of complex conditional flow and variable scope, to see the value of structured languages. .

The Last Step: Objects

The most recent step, object orientation, introduces even more subtle refinements. You won’t see its practical benefits in a one-line or even 30-line program, but in much, much longer programs, possibly thousands of lines long. Again, this is not because object orientation is a waste of time, but because each successive generation of programming languages addresses larger and more general issues of program organization.

If you’re a professional programmer—or even a dedicated student or hobbyist—you probably do write programs thousands of lines long. Therefore, with a little patience, you should see ways to improve program organization with object-oriented languages such as C++.

The object-oriented approach is to determine the principal data structures of your program and then organize functions by the data on which they operate. Object orientation tends to make very large programs easier to deal with. The traditional approach to programming regards functions and data structures as separate entities. That’s fine when you have only a dozen or so of each, but when you have hundreds of structures, it’s difficult to remember what function is supposed to work on what data.

C++ enables you to build the relationship of functions to data structures into the source code itself. It also enables you to use these relationships as the basis for privacy and data access. These features not only make the workings of the code more obvious to others who have to maintain it, but prevent many causes of errors

Objects and Graphical Systems

Perhaps the most natural real-world application of objects is in the world of graphical systems. An object on the screen clearly has associated data: its size, location, etc. At the same time, a graphics program gives you ways to manipulate that object: you can change its size, color, and so on. This functionality can certainly be provided through traditional programming, but object orientation makes the connection between code and data more explicit in the code itself. For example:

   class CCircle {
   // Data members for the circle
     private:
   CPoint center;
   long radius;
   // Functions for manipulating the circle
   public: //
   void Move(CPoint);
   void Resize(long);
   void Redraw(void);
 };

The workings of a graphics program make the connection between functions and data particularly important. Considering how the program works, you’d want the fundamental units of organization to be circle, square, line, triangle, etc., rather than functions vs. data. And that’s the essence of object orientation.

Graphical user environments are also natural places to use object orientation. It’s no coincidence that the Microsoft Windows operating system uses many such concepts: Windows are registered as classes and then instantiated, just as objects are. Window classes can be subclassed, which is really what inheritance in C++ does. Windows communicate with each other by sending messages, which are much like method calls. Windows apologists sometimes say that Windows-based programming is object-based, not object-oriented, but my own feeling is that (to quote Shakespeare) "the lady doth protest too much." The architecture of Windows truly involves object-oriented ideas. This is why building Windows-based programs with an application framework (such as Microsoft Foundation classes) is a natural way to capitalize on the real-world usefulness of C++.

Objects and the Future of Object-Oriented Systems

In the future, systems programming is liable to utilize object-oriented concepts even more than Windows does now. A leading architecture in this area is OLE 2.0, with its Component Object Model (COM). The systems programming models of the future take the object-oriented concepts of languages such as C++ and raise them to the system -level, enabling any object in the system to communicate with any other object in a standard way.

COM is a binary standard, meaning that you can write all the code in C, as well in as C++. But it’s no coincidence that statements that use or implement COM are always easier to express in C++. Consider this common method call written in C++:

   pInterface->Release();

Here’s what it looks like in the C version:

   pInterface->lpVtbl->Release(pInterface);

The C++ version is obviously more concise. This is because there is harmony between the concepts of C++ and COM. A C++ object and a COM object are not identical concepts, but they have many things in common. C++ is a tool that expresses the ideas of COM much more naturally than non-object-oriented languages do.

Getting Started With C++

So object orientation is most helpful in large programs and in interaction with large, object-oriented systems (Windows, for example). However, object-oriented concepts and structures may be difficult to introduce into an existing code base. It takes great effort to pull apart and redesign a program. If you’re fortunate, you can start using C++ on a new project.

Lacking that, the most practical way to start gaining benefits from C++ is to start building re-usable components that you can use in your project now. Or you can find components in an application framework (for example, the CString class in MFC) and start using them right away. C++ won’t produce components for you, but it does provide a superior way of packaging them for reuse.

There’s nothing magical about C++; like any language, it’s only a tool. In the systems of the future, however, you’ll find that this tool will become almost a requirement, one that will ultimately repay your learning efforts.

Brian Overland has published several books on C and C++, one of which has been translated into Polish and Croatian, and has written on programming topics for many groups at Microsoft. Before coming to Microsoft as a technical writer, he was a professional programmer, actor, and drama critic.

Some languages express certain ideas more easily than others.

C++ can express everything that C can, and then some.

C++ enables you to build the relationship of functions to data structures into the source code itself.

It’s no coincidence that statements that use or implement COM are always easier to express in C++.