Register for EarthWeb's Million Dollar Sweepstakes!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

C++ in Plain English
(Publisher: IDG Books Worldwide, Inc.)
Author(s): Brian Overland
ISBN: 1558284729
Publication Date: 04/01/96

Bookmark It

Search this book:
 
Previous Table of Contents Next


Other Constructor Examples

As another example, consider the CTemp_point class introduced in Chapter 5. This class produces objects that record a point on a three-dimensional grid and a temperature at that point. Along with the code in Chapter 5, I’ve added several constructors:

class CTemp_point {
    int x, y, z;
    double temp;
public:
    CTemp_point();
    CTemp_point(int xx, yy, zz);
    CTemp_point(CTemp_point& pt);

    void set_point(int xx, yy, zz);
    void get_point(int *xx, *yy, *zz);
    void set_temp(double new-temp);
    double get_temp(void);
};

The first and third constructors in this declaration are, respectively, the default constructor and the copy constructor. The CTemp_point class is much simpler than the CStr class—there is no dynamic memory to allocate, reallocate, or clean up—so in this case, there is nothing for the default constructor to do. However, for reasons explained earlier, you must include the default constructor. Otherwise, C++ assumes that there is no default constructor and prevents you from (for example) using the new operator or declaring uninitialized objects.

The default constructor is easy to write, to put it mildly:

CTemp_point::CTemp_point() {
}

The next constructor is slightly more interesting. Note that it has three arguments. Constructors may have any number of arguments.

CTemp_point::CTemp_point(int xx, int yy, int zz) {
    x = xx;
    y = yy;
    z = zz;
}

Finally, the copy constructor initializes an object by copying the data members of its argument, pt. This argument is another object of type CTemp_point. This constructor could be omitted from the program code with no effect, because it performs the same actions (member-by-member copy) as the compiler-supplied copy constructor:

CTemp_point::CTemp_point(CTemp_point& pt) {
    x = pt.x;
    y = pt.y;
    z = pt.z;
    temp = pt.temp;
}

Each of the following three statements makes a call to one of the three constructors:

CTemp_point pt1;
CTemp_point pt2(100, 101, 200);
CTemp_point pt3(pt2);

How C++ Calls Constructors (Conversion)

C++ calls constructors in ways you might not expect. Consider the following declarations:

CStr name1(“John Doe”);
CStr name2 = name1;
CStr name3 = “Jane Doe”;

Clearly, the first declaration results in a call to the constructor CStr(char*). More surprising, the second declaration also calls the copy constructor. This is not obvious. You might think that the second statement creates name2 by calling the default constructor and then performs an assignment from name1 to name2. However, it doesn’t do either of these things. The following declarations are exactly equivalent, not only in ultimate effect but also in the way constructors are called:

CStr name2 = name1;
CStr name2(name1);

In C++, assignment and initialization are sharply distinguished (there is no overlap) even though they look much the same. Except in a variable definition, the equal sign (=) always indicates assignment. Within a variable definition, however, the equal sign always indicates initialization, which results in a call to the appropriate constructor and not to the assignment operator.

As you’ll discover in the next chapter, assignment is an operator whose behavior you can define. It is not the same as the copy constructor. One would expect the copy constructor and the assignment operator to do the same thing, but this is not true in all cases. (The main difference is that a copy constructor cannot assume that an object was previously initialized and may therefore have to do a little more work.)

Similarly, the final declaration calls the constructor CStr(char*):

CStr name3 = “Jane Doe”;

There’s another case in which constructors are called: conversion from other data types to the class in question (in this case, CStr). A constructor does double duty as a conversion function whenever the following conditions are met: there is exactly one argument, and the type is not the same as the class itself. (in other words, the copy constructor is not a conversion function.)

The constructor CStr(char*) tells the compiler how to convert a char* string into a CStr object. Consequently, you can use a char* string wherever a CStr object is expected, and the compiler will convert it for you. For example:

CStr make_uppercase(CStr s); // prototype

CStr string1;
string1 = make_uppercase(“cia/fbi”);

The last line of this code sequence makes a call to the constructor CStr(char*) to create a CStr object from the string “cia/fbi”. The resulting object is then passed to the function convert_to_upper.

Summary: the Key Points of Construction

Constructors may seem like a trivial topic at first, but as it turns out, there are important things to say about them. The major points are summarized in the next few sections.

Overloaded Constructors

The name of a constructor is always that of the class itself. So for the CStr class, every constructor is named CStr. There is no return type, not even void.

As with most C++ functions, constructors can be overloaded. This means that you can reuse the same name with different argument lists (in this case, only the number and types of the arguments matter). The significance for this chapter is that you can create a number of constructors, each of which uses a different argument or arguments to initialize an object.

The Default Constructor

class();

One of the most important constructors is the default constructor—which for any given class is the constructor that has no arguments. This constructor is called when you define an object without initialization, create an uninitialized array of objects, or use the new operator. The compiler is a little deceptive because it creates a hidden default constructor for you, unless you add any constructors of your own, in which case the hidden default constructor goes away. This is why, you should write your own default constructor, even if it doesn’t do much.

The Copy Constructor

class(class&);

The copy constructor is another constructor of great importance for each class. Its most obvious use is to initialize an object from another object of the same type. But this constructor is also called when you pass the type by value or you use the type as the return value in a function call. The compiler always supplies a hidden copy constructor if you don’t. Remember, though, that this compiler-supplied constructor performs a simple member-by-member copy that for a class such as CStr, is inadequate. If in doubt, write your own constructor.

The argument to a copy constructor uses the reference operator (&), which means to pass by reference as in Basic or FORTRAN—without pointer syntax.

Initialization and Conversion

Object definition and initialization always invoke constructors, even when they use the equal sign (=). In this context, the equal sign does not mean exactly the same thing as assignment.

CStr string1 = “Hi world!”; // Call CStr(char*)

Another case in which constructors are automatically invoked is in type conversion. Given the constructor CStr(char*), you can pass a char* argument where CStr is expected, and the compiler performs the conversion for you.

With preliminaries such as classes and constructors out of the way, we can move on to one of the most interesting, time-saving aspects of C++: operator overloading.


Previous Table of Contents Next
[an error occurred while processing this directive]

Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.