top of page
Separating class implementation and interface

The general convention in C++ is to write

  • class definition with member function declarations and data member definitions in a .h file

  • definitions of member functions in a separate .cpp file.

 

This way we can separate interface of a class from its implementation.

 

And, if and when the implementation changes, users of the class are not affected by the change.

 

Let us see how to write implementation of class methods outside of class body.

Let us consider a class circle. Here is circle.h file

Now let us write implementation of find_area function in another file circle.cpp

Note that we have to include the  header file - circle.h header file here.

The find_area() function must be preceded by class name and operator ::. This operator :: is called scope resolution operator.

 

The prefix circle:: tells the compiler that the function is member of circle class, not an independant global function. 


When we write definition of member functions outside of class, we have to always add a prefix of class name and scope resolution operator.
 

Note : Scope resolution operator specifies the scope of the name. But it is also used to identify the name-space. To use cout and cin for I/O , we can use std::cout and std::cin, instead of using "using namespace std".


Finally we write our main function and user program in a third file main.cpp

As this needs to use circle class, we use #include  "circle.h" statement. 

How do we compile this?

      g++ circle.cpp main.cpp 

We have to compile our main as well as class cpp file together.

Note: In future sample programs, I will not split the class into declaration and method definitions, just for the sake of brevity.

Let us come back to output of the program.

 

If we execute the program, we notice that, we get some random answer. What is this and why do we get a different answer each time.

Because we have not initialized radius of the class. So shall we set it to something? But how?  radius is a private data. So main() can not access it. 


Uninitialized data members of a class have garbage value. There must be some function where we can initialize the data members of a class automatically.

Such a function does exist and it is called constructor. A constructor of a class is function which initializes the state of an object when it is created.

A C++ class also has another function called destructor which cleans up the object when it is being destroyed.

Constructors and destructors :

A class will have   special member functions called constructors and destructors which are used to initialize and clean up the object. Like other member functions, these are declared within a class. These functions can call other member functions of the class including virtual functions.

Constructor


A constructor is a special member function of a class which initializes the object and is called automatically when an object is created.

 

What will be the name of a such a  constructor function?

 

Constructor of a class has the same name as class, and it has no return type. So in the case of circle class, constructor will be circle().

 

Here are some more interesting facts about constructor

  • Constructor has same name as class.

  • Constructor has no return type. Not even void!

  • Constructor can have 0 or more parameters.

  • Constructor can be overloaded  - a class can have multiple constructors.

  • Constructor is called automatically when ever an object of the class is created.

In the above program, for the class circle, we have two constructors  - circle(float) and circle(float,int,int int).

So the name of these constructors is circle - class name. These constructors have no return type.

How did they get called in the above program?

 

They were called when we created the objects c1 and c2. c1 creation called 1 parameter constructor as we passed one value to it. c2 creation called three parameter constructor because we sent three values - 2,10,10.
 

Passing values to constructors

If a constructor is not called explicitly, how are arguments passed to it?

 

Arguments are sent within parentheses next to the object name when defining the objects.

   e.g. 

    Circle c1(7), c2(2,10,10);

 

Here we are sending one argument 7 as a parameter to the constructor of object c1 and 3 arguments to the constructor of c2.

Default constructor

 

If a constructor takes 0 parameters or it has default values for all parameters, then it is called default constructor.  In our example of circle class, default constructor will be circle(){...}

 

Whenever an object is created without sending any values, default constructor is called. If we say circle c1;, the default constructor is called. 

 

Default constructor is also called when an array of objects is created.

Output of the above program:


constructor
parameterized constructor
Number is 3
constructor of B
constructor of B
constructor
constructor
constructor
constructor


Class A in this example has a default - zero parameter constructor. And class B has a one parameter constructor, but has default value for that parameter. So both of these are default constructors.

NOTE :

 When a class has no user defined constructors, the compiler provides a default constructor for the class which is trivial.

Class C above  does not have any constructors. So compiler provides a default constructor which is trivial.

Now let us modify class A and remove the default constructor.

Now if an object of class A is created without argument as in obj2 in the example, there will be a syntax error. As class A has a constructor, compiler is not providing any default constructor. So obj2 can not be created.


 

Exercise : Comment the constructor of A class now. And observe what happens to  the line A obj2;


Let us revise with few questions on default constructor here.
 

Which of the following are valid default constructors of a class Rectangle?

  1. Rectangle::Rectangle(int side=0);

  2. void Rectangle::Rectangle();

  3. Rectangle::Rectangle(int s);

  4. Rectangle::Rectangle();

Answer:

  1. 1 is a valid default constructor. Though it has a parameter side, there is a default value to it. Which means it can be called without passing any values.

  2. 2 is invalid because constructors do not have return type. Not void also.

  3. 3 is invalid because, this constructor has one parameter.

  4. 4 is valid default constructor.

Member Initializer Lists


A constructor can initialize data members using member initializer list . Initializer list is more efficient than assignment in constructor. The member initializer list is written as a list as shown in example below.

In the above example, a(m),b(n) is member initializer list. Data member a is set to m and  b is set to n using the initializer.

Member initializer are also useful for calling base class constructors or constructors of member objects. 
 

There are certain cases where one must use member initializer lists.

 

A class must use  member initializer list if

  1. it has constant members.

  2. it has reference members.

  3. it has base classes with no default constructors.

  4. it has member objects with no default constructors.

In the above example, as the class A has a constant member. Now you should use member initializer list for constant n. You should re-write constructor of the class as 

 

A(int x,int y):m(x),n(y){}

bottom of page