Constructors and Destructors


Remember that a class is a rather complex data type. You will frequently find that there are some initial settings you might want to establish before a class is used. You might also need to retrieve data from some flat file or even a relational database. Most of this should be done before any methods of the class are called. You can do this in a constructor. A constructor is a function that has the exact same name as the class and is called when you instantiate the class. Constructors do not have any return type at all, not even void. Constructors can be very useful for setting initial values for certain member variables. Example 10.5 should help you to understand this.

Example 10.5

Step 1: Create a plain text file named input.txt that has exactly what you see here:

“Hello C++ Programmers.”

Step 2: Please enter the following code into your favorite text editor.

#include <fstream> #include <iostream> using namespace std;   class myfirstclass { private:       char msg[20];       int loopcounter;       fstream myfile;       public:  void greeting();   myfirstclass(); }; myfirstclass::myfirstclass() {      //open the file with the data      myfile.open("input.txt",ios::in);      myfile.getline(msg,20); }   void myfirstclass::greeting() {       cout << msg << "\n"; } int main ()  {      myfirstclass myfirstobject;      myfirstobject.greeting();  return 0; }

Step 3: Compile the code.

Step 4: Run the code. You should see something similar to Figure 10.6.

click to expand
Figure 10.6: Constructors.

As you can see, the data printed-out to the screen is the same as what was retrieved from the text file. The constructor opened that file and put the data into the appropriate variables. Doing this in the constructor ensured that there was zero chance of trying to use one of the methods before the data was loaded into the variables.

Now we have a function that is called as soon as a class is instantiated. It can be used to initialize variables and retrieve data. But what about clean up? If we opened a flat file where do we close it? If we accessed a relational database, where do we close that connection? The answer is a destructor. A destructor is called when you destroy an object. A destructor is created much like a constructor, except the name is preceded by the negation symbol ~. The destructor will be executed as soon as the instance of the class goes out of scope—the end of the function in which the object was created. The following example illustrates this.

Example 10.6

Step 1: Please enter the following code into your favorite text editor.

#include <fstream> #include <iostream> using namespace std;   class myfirstclass { private:       char msg[20];       int loopcounter;       fstream myfile;       public:  void greeting();   myfirstclass();  ~myfirstclass(); }; myfirstclass::myfirstclass() {      //open the file with the data      myfile.open("input.txt",ios::in);      myfile.getline(msg,20); } myfirstclass::~myfirstclass() { myfile.close(); } void myfirstclass::greeting() {       cout << msg << "\n"; } int main ()  {      myfirstclass myfirstobject;      myfirstobject.greeting();      return 0; }

Step 2: Compile the code.

The destructor closed the file for us, ensuring that we don’t leave a file handle, or any other resource, still in memory. It is important that C++ programmers clean up after themselves.

If you will recall from the chapter on functions, it is possible to overload a function. An overloaded function occurs when you have multiple functions with the same name, but with different parameters. Overloaded functions can have either different numbers of parameters, or different types of parameters. You can overload constructors as well. The constructor that takes no arguments is the default constructor. Let’s consider an example that will illustrate this for you.

Example 10.7

Step 1: Enter the following code into your favorite text editor.

#include <fstream> #include <cstring> #include <iostream> using namespace std;   class myfirstclass {   private:       char msg[20];       int loopcounter;       fstream myfile;        public:   void greeting();    myfirstclass(char greeting[20]);   myfirstclass();   ~myfirstclass(); }; myfirstclass::myfirstclass() {      //open the file with the data      myfile.open("input.txt",ios::in);      myfile.getline(msg,20); } myfirstclass::myfirstclass(char greeting[20]) {  memcpy(msg,greeting,sizeof(msg)); } myfirstclass::~myfirstclass() {  myfile.close(); } void myfirstclass::greeting() {       cout << msg << "\n"; } int main ()  {  myfirstclass myfirstobject("Howdy from Texas!   ");      myfirstobject.greeting();      return 0; } 

Step 2: Compile the code.

Step 3: Run the code. You will see something like what is depicted in Figure 10.7.

click to expand
Figure 10.7: Multiple constructors.

As you can see in this example, you have two constructor functions. C++ determines which constructor to use by how you call it. If you create an instance of the object without passing it any parameters, then it will call the default no-argument constructor. If you pass it a character array, then it will call the constructor that takes a character array argument. If you pass it some other argument such as an int or a float, you will get an error.

Also notice the use of the memcpy function. This was first introduced in the chapter on functions. It copies contents from one array or structure (in our case, a character array) to another. The last parameter of that function is telling it how much to copy. Recall that you can enter a number and designate a certain number of bytes. However in this case, we used another function, sizeof, and told the function to copy a number of bytes equal to the size of the msg array.




C++ Programming Fundamentals
C++ Programming Fundamentals (Cyberrookies)
ISBN: 1584502371
EAN: 2147483647
Year: 2005
Pages: 197
Authors: Chuck Easttom

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net