Reliable Software Logo

C++ In Action: Language

Global scope

Class definition, object definition, constructor, destructor, output stream, include, main.


There is an old tradition in teaching C, dating back to Kernighan and Ritchie (The C Programming Language), to have the first program print the greeting "Hello World!". It is only appropriate that our first C++ program should respond to this greeting. The way to do it, of course, is to create the World and let it speak for itself.

The following program does just that, but it also serves as a metaphor for C++ programming. Every C++ program is a world in itself. The world is a play and we define the characters in that play and let them interact. This program in a sense is "the Mother of all C++ programs," it contains just one player, the World, and lets us witness its creation and destruction. The World interacts with us by printing messages on the computer screen. It prints "Hello!" when it is created, and "Good bye!" when it vanishes. So here we go:

#include <iostream>

class World
{
public:
    World ()  { std::cout << "Hello!\n"; }
    ~World () { std::cout << "Good bye!\n"; }
};

World TheWorld;

int main() {}

This program consists of the following parts:

  • The include statement,
  • The class definition,
  • The object definition, and
  • The main routine.

Let's start from the end, from the main function, and work our way backwards. Whenever you see something weird in C++ it is probably there for the sake of compatibility with C. That's the case with main()1. In this particular program it serves no purpose whatsoever, and in fact is quite empty. It takes no parameters--you can tell that from the empty set of parentheses; does nothing--you can tell that from the empty set of braces; and returns nothing interesting (it has to be defined as returning an integer, hence the int in front of it, but you don't have to provide a return value). But main just has to be there.

The line:

World TheWorld;

defines the object TheWorld of type World. You can also say, TheWorld is an instance of the class World. Like every statement in C++, it is delimited by a semicolon. (Quick exercise: Find all the statements in our program.)

This is the central line of the program. Show this program to a C programmer and ask him what it does. He will say "Nothing!" That's because a C programmer looks at main() and sees nothing there. The trained eye of a C++ programmer will spot the global definition of TheWorld and he will say "Ha!"

Global means "outside of any curly braces." All this space outside of the curly braces is considered the global scope, Figure 1.

Global Scope

Figure 1 Global scope is everything outside of curly braces.


Next, following our inverted order of analysis, is the definition of the type World. It turns out that World is a class-that is a type defined by the programmer. The definition is inside curly braces (and is delimited by a semicolon, did you miss that one?). The keyword public means that we have nothing to hide yet. Later we'll learn about data hiding and we won't be that open any more.

First inside the class definition is the constructor. Constructor is a piece of code that is to be executed every time an object of this particular class is created. It always has the same name as the class itself, but it may take arguments-that's why it has a set of parentheses following it-they're empty, so this particular one doesn't take any arguments. The constructor does something-the curly braces following it are not empty. They contain the statement

std::cout << "Hello!\n";

It means that the object std::cout is sent the string "Hello!\n". This particular predefined object std::cout represents the standard output, presumably the screen of the computer, and it prints whatever is sent to it using the special notation: <<. (Now we know where this "Hello!" came from.) By the way, '\n' (backslash n) at the end of the string means "newline"-so that the next printout will start on a new line.

Next is the destructor, which always has the same name as the class but is preceded by a tilde. It is the piece of code that is executed every time an object of this class is destroyed. It never takes any arguments, so the parentheses following its name are always empty. The destructor of World also does something. It prints "Good Bye!\n".

At the top of the file we have an include statement. It tells the compiler to find the file iostream and include it right there. If your compiler is properly installed, it will find it; if not, reinstall it or read the manual. (Sorry, I have no idea what compiler you are using.) The compiler needs this file to find out what the heck std::cout is and what can be done to it. This object (of the class iostream) is part of the standard C++ library, not part of the language.

The order in which we have analyzed this program was far from random. It is called top-down and is the right way of looking at programs (and writing them, too). If you're confused where the top is and which way is down, just imagine that the program has a third dimension and it looks sort of like a set stairs, Figure 2. The main routine sits at the top of the stairs, closer to you. Global definitions are one step lower. Class definitions are next, and so on.

Stairs

Figure 2. Trying to visualize the top-down view of the program. Imagine that the top is closer to you and the bottom is further from you.


The stage is now set, the main player is TheWorld. Its character is defined by the class World-it does something when it is constructed and does something when it is destroyed. The play starts. Here's what happens:

  1. All global objects are constructed. In our case the constructor of TheWorld is executed and prints "Hello!" on the screen.
  2. The main routine is executed. In our case it does something very important. It makes C programmers happy.
  3. All global objects are destroyed. In our case the destructor of TheWorld is executed and it prints "Good bye!"
That's it!

Well, not really. If programming were that simple, everybody would be a programmer. In order to make it difficult there is a whole lot of magical incantations that have to be typed into the computer in order to make the program run. It's these incantations that provide our job security. I can tell you what incantations I had to type into my computer in order to run this program. And I am already assuming a lot. That I am in the proper directory, that I have the file world1.cpp in it, that the compiler is properly installed, and so on, so forth. I typed

cl world1.cpp

cl is the nickname of my C++ compiler. Yours might have a different nickname, so check with you compiler manual. Once the compilation was finished, I just typed

world1
and voila! By the way, this is the name of the resulting program on my system.

One more hint. If the compiler refuses to compile your program, look at its output. It is supposed to tell you where and what errors it has found. If you understand these error messages, you are probably an experienced programmer already. If you don't, don't despair. Only experienced programmers can understand them.

Your best bet is probably some kind of an integrated programming environment, with a built-in editor, compiler, debugger and more. You'll be able to build and run your program with a single mouse click. Well, not exactly. You usually have to tell the program that you want to create a new project. The type of the project, in our case, is a console application (as opposed to a Windows application). Then you have to create a new file, type in the code and save it under the name world1.cpp. Next, and I'm not making it up, you must tell the program to add the file you have just created (with the above mentioned program's help) to the project. Once the file is in the project you'll need to build the executable. Building means compiling and linking. If there are any compilation errors, you'll be able to jump to the line in your program that caused the error and try to correct it.

In most environments, after you've successfully built your program, you can single-step through it under a debugger. You'll be able to see how each statement is executed and how it changes the state of the program.


To summarize, we have introduced a class and an object. Think of a class as a blueprint for an object. It describes the object's behavior-in our case, what happens when the object is constructed and destroyed. Once you have a blueprint, you can create objects that are based on it.


NextNext: Local Scope


1 One could think of main as the constructor of the global Main object. This is how truly object oriented languages work.