I l@ve RuBoard |
Default Constructors
Many classes do not need constructors because class objects do not need default initialization. When the class designer does not add any constructors to the class, the system provides a default constructor (which does nothing) for the class.
class Cylinder { // OK if no constructors/destructors
double radius, height; // data is protected from client access
public:
void setCylinder(double r, double h); // methods are accessible
double getVolume();
void scaleCylinder(double factor);
void printCylinder();
} ; // end of class scope
All of the versions of class Cylinder that I discussed in the previous section were using the system-supplied default constructor. I did not mention it to avoid unnecessary complication of the discussion. When the client code creates a Cylinder object, this default constructor is called.
Cylinder c1; // default constructor is called, no initialization
Why should you know about this? After all, this constructor does not do anything. What you should know, however, is that if a class defines a nondefault constructor (constructor with parameters), then the system no longer supplies the default constructor.
Why should you know about that? Because syntactic errors occur if the client designer defines class variables and arrays that need the default constructor.
This last version of class Cylinder did not have programmer-defined constructors. Hence, the system gave this class Cylinder the default constructor that did nothing. When variable c1 was created, that constructor was called. How do I know that? Well, some constructor must be called. (There is no such thing anymore as object creation without a constructor call.) Which constructor? That depends on the number of arguments supplied. The variable c1 does not have any arguments supplied. This is evidence that a constructor without arguments is called (remember that joke about copper wire?). A constructor without arguments is a default constructor. Does the class provide the default constructor? No. Does the class provide any constructor? No. Hence, the default constructor is supplied by the system. It does nothing. Everything is fine.
Let us look at a version of class Cylinder that provides a general programmer-defined constructor. This means that the system takes the default constructor away.
class Cylinder {
double radius, height;
public:
Cylinder(double r, double h) // this is not enough
{ radius = r; height = h; }
. . . } ;
When the client code tries to create Cylinder objects, trouble follows.
Cylinder c1(3.0,5.0); // this is OK
Cylinder c2, c[1000]; // 1001 syntax errors
Cylinder *p = new Cylinder; // one syntax error
Here, I create 1001 Cylinder object instances without supplying arguments. Recall that there is no creation of an object without constructor calls? So the compiler tries to generate code for 1001 constructor calls. Which constructor? Since I did not specify any arguments, the compiler is trying to call a constructor with no arguments, that is, a default constructor Cylinder::Cylinder(). But this version of class Cylinder does not define a default constructor. Since it defines a general constructor, the system takes the default constructor away. What happens when the client code calls a member function 1001 times to initialize 1001 Cylinder objects? Since this function is not found in the Cylinder class specification, the compiler generates a syntax error. Make sure that you learn to rush through this logical derivation quickly.
The problem can be resolved by supporting the client code with a programmer-defined default constructor. This default constructor could do nothing, similar to the system-supplied default constructor, or it could initialize object data members to some reasonable values.
class Cylinder {
double radius, height;
public:
Cylinder () // programmer-supplied default constructor
{ radius = 100.0; height = 0.0; } // reasonable values
Cylinder(double r, double h) // general constructor
{ radius = r; height = h; }
. . . } ;
Client code:
Cylinder c1(3.0,5.0); // this is OK
Cylinder c2, c[1000]; // now this is OK, too
Cylinder *p = new Cylinder; // no syntax error
Notice that the creation of each object is accompanied by at least one function call; here, constructors are inline functions; still, this can have performance implications. There is no such thing in C++ as the creation of an object without a function call.
NOTE
Creation of objects in C++ is always followed by a constructor call. If the class defines no constructor, creation of objects is followed by a call to a default constructor supplied by the system. If the class defines any constructor, the system does not supply the default constructor. In this case, you cannot create arrays of objects or objects without arguments. The system gives, the system takes away.
I l@ve RuBoard |
No comments:
Post a Comment