Object Initialization & Constructor Functions
One of the most crucial sources of errors in programs in
initialization of objects. Many objects have interesting requirements
as it relates to initialization.
For example, we might have a requirement that EVERY car (the moment it
is created) MUST have a serial number and price. How can we ensure
that no car is ever created by any programmer that violates this
requirement? It is not easy, but fortunately, C++ provides a way.
C++ provides a very good way to ensure that objects are initialized in
the appropriate manner without ANY exceptions. Initialization is
simply an extension of the idea of encapsulation. If the member
functions of the class protect the values of the attributes stored
inside the object, it is very important that the object had the right
set of values to start with!
How does C++ support initialization?
C++ supports the idea of "the constructor of a class". The
constructor of a class is:
a) A member function of that class
b) It has the SAME NAME AS THE CLASS
c) The constructor function has no return type
The constructor function typically appears as a public member function
of the class. It is AUTOMATICALLY invoked whenever any object of that
class is created. In short, the programmer instantiating the object
cannot inadvertently forget the initialization requirements or
intentionally not initialize the object.
E.g., in the Car example, in order to initialize every car so that it
has a serial number and price,
class Car
{
public:
// prototype for the constructor...
Car (string ser, int pr);
private:
string serial;
string manufacturer;
string model;
int seats;
int price;
};
// Constructor body defined outside the class:
const string DUMMY_SERIAL = "ZZ00000000";
Car::Car (string ser, int pr)
{
if (ser.size == 10 &&
isdigit(ser[0]) &&
isdigit(ser[1]) )
serial = ser;
else
{
cout << "Illegal serial: " << ser << " . Assigning dummy..."
<< endl;
serial = DUMMY_SERIAL;
}
}
Now, of course, you want this code for the constructor to go into
the file Car.cpp, since it is part of the class code.
In the main program:
main ()
{
Car X("WR12345678", 20000); // perfectly legal
Car Y("&*90909090", 25000); // will compile, but
// serial number will be dummy
Car Z; // NOT LEGAL -- you need to provide parameters
// to the constructor function!!!!!
}
Once the constructor is specified by the programmer of Car, users of
Car MUST instantiate the Car object the right way or pay the price of
having the compiler flag their attempt to circumvent the rules!!!
constructor1.cpp [ shows constructor working ]
So, how did:
Car X;
work before? Because C++, out of the kindness of its heart, gave you
what is called a DEFAULT constructor -- i.e., a constructor with no
parameters. Since we said nothing about a constructor, C++ provides a
default constructor that does nothing to let you create objects. Once
you specify a constructor, C++ assumes you want to take charge of
initialization yourself.
It is important to spot when constructors are being called. They will
INVARIABLY be called when objects are created. For now:
{
Car A;
...
}
when you enter a block, all the variables/objects you need to enter
the block are create. So, you call the constructor for all objects
created inside the block, such as A above.
for (int i = 0; i < 10; i++)
{
Car X;
...
}
How many times is the constructor for Car called in the code above?
It is 10 times! Each time you enter the block after the for
statement, you create the object X. Each time you leave the block X
(i.e., at the closing of the block at } ), you de-allocate the object.
So, C++ objects come and go as you enter and leave "blocks", defined
by matching sets of "{" and "}".
Destructor
What if you wanted to do something when any object is de-allocated?
C++ provides a destructor function that you can define for a class.
The destructor for a class has the following rules:
a) it is a member function with name ~class_name (e.g., ~Car for
the Car class.
b) It has NO parameters and NO return type
The destructor, if defined, is automatically called whenever an object
of type Car is destroyed.
class Car
{
public:
Car (string ser, int pr);
// prototype for the destructor...
~Car();
private:
string serial;
string manufacturer;
string model;
int seats;
int price;
};
************* code for destructor in Car.cpp **********
Car::~Car()
{
cout << "Sad that a car was destroyed!!" << endl;
}
constructor2.cpp [ shows constructor and destructor ]
Building a Class-Based Database Program (Array Implementation)
In this example, we show how to operate with multiple classes.
You have already learned how to program a database using an array. In
this case, we will encapsulate the database itself using a class. The
array representing the database will be a private data member of the
class.
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees