MFC Programmer's SourceBook : Thinking in C++
Bruce Eckel's Thinking in C++, 2nd Ed Contents | Prev | Next

Guaranteed initialization with the constructor

Both the Stash and Stack classes have had functions called initialize( ), which hint that it should be called before using the object in any other way. Unfortunately, this means the user must ensure proper initialization. Users are prone to miss details like initialization in their headlong rush to make your amazing library solve their problem. In C++ initialization is too important to leave to the user. The class designer can guarantee initialization of every object by providing a special function called the constructor. If a class has a constructor, the compiler automatically calls that constructor at the point an object is created, before users can even get their hands on the object. The constructor call isn’t even an option for the user; it is performed by the compiler at the point the object is defined.

The next challenge is what to name this function. There are two issues. The first is that any name you use is something that can potentially clash with a name you might like to use as a member in the class. The second is that because the compiler is responsible for calling the constructor, it must always know which function to call. The solution Stroustrup chose seems the easiest and most logical: The name of the constructor is the same as the name of the class. It makes sense that such a function will be called automatically on initialization.

Here’s a simple class with a constructor:

class X {
  int i;
public:
  X();  // Constructor
};
Now, when an object is defined,

void f() {
  X a;
  // ...
}
the same thing happens as if a were an int: Storage is allocated for the object. But when the program reaches the sequence point (point of execution) where a is defined, the constructor is called automatically. That is, the compiler quietly inserts the call to X::X( ) for the object a at its point of definition. Like any member function, the first (secret) argument to the constructor is the address of the object for which it is being called.

Like any function, the constructor can have arguments to allow you to specify how an object is created, give it initialization values, and so on. Constructor arguments provide you with a way to guarantee that all parts of your object are initialized to appropriate values. For example, if the class Tree has a constructor that takes a single integer argument denoting the height of the tree, you must then create a tree object like this:

Tree t(12); // 12-foot tree

If tree(int) is your only constructor, then the compiler won’t let you create an object any other way. (We’ll look at multiple constructors and different ways to call constructors in the next chapter.)

That’s really all there is to a constructor: It’s a specially named function that is called automatically by the compiler for every object. However, it eliminates a large class of problems and makes the code easier to read. In the preceding code fragment, for example, you don’t see an explicit function call to some initialize( ) function that is conceptually separate from definition. In C++, definition and initialization are unified concepts – you can’t have one without the other.

Both the constructor and destructor are very unusual types of functions: They have no return value. This is distinctly different from a void return value, where the function returns nothing but you still have the option to make it something else. Constructors and destructors return nothing and you don’t have an option. The acts of bringing an object into and out of the program are special, like birth and death, and the compiler always makes the function calls itself, to make sure they happen. If there were a return value, and if you could select your own, the compiler would somehow have to know what to do with the return value, or the user would have to explicitly call constructors and destructors, which would eliminate their safety.

Contents | Prev | Next


Go to CodeGuru.com
Contact: webmaster@codeguru.com
© Copyright 1997-1999 CodeGuru