Skip to main content

Constructor of a class

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

By writing class member functions outside, you are not exposing implementation to the user of the class. And if you have to change the implementation user is not affected.

circle.h

class circle
{
   float radius;
   int x, y;
public:
   float find_area();   
};
This is the declaration of the class.

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

#include"circle.h"
float circle::find_area()
{
    const float PI = (float)22/7;
    float area = PI * radius*radius;
    return area;
}
Note how we have to include the circle header file in this.

The find_area() function must be preceded by class name and ::. :: is called scope resolution operator. circle:: tells us that the function is member of circle class not a global function. 

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

Note : Scope resolution operator specifies the scope of the name. 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 third file main.cpp

As this needs to use circle, this also includes circle.h 

#include<iostream>
#include"circle.h"
using namespace std;
int main()
{
    circle c1;
    cout<<c1.find_area();
}
But how do we compile this program which is split into three different files?

g++ circle.cpp main.cpp 

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

And the output of the program is
5.33388e+18u


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

Let us come back to output of the program. What is this and why do we get a different answer each time.

Because we have not initialized radius of the class. And we are not able to access it.

There must be some function we can initialize the data members of the class.

Such a method is called constructor.

Constructor

A C++ class has two special member functions called constructor and destructor used for initializing and cleaning the object.

A constructor is a special member function of a class which initializes the object and is called automatically when an object is created. Constructor has same name as class, and it has no return type.

Here are some more facts about constructor
  • Constructor has same name as class.
  • Constructor has no return type. No, 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 an object of the class is created.
Let us write our circle class with constructors.


#include<iostream>
using namespace std;
class circle
{
   float radius;
   int x, y;
public:
   float find_area(); 
   circle(float r);//constructor
   circle(float r,int cenx,int ceny); //constructor
}; 
float circle::find_area()
{
    const float PI = (float)22/7;
    float area = PI * radius*radius;
    return area;
}
 
circle::circle(float r)
{
    radius = r;
    x = y = 0;
}
circle::circle(float r,int cenx,int ceny)
{
    radius = r;
    x = cenx;
    y = ceny;
}

int main()
{
    circle c1(7);
    circle c2(2,10,10);
    cout<<"Area of first circle: "<<c1.find_area()<<endl;
    cout<<"Area of second circle: "<<c2.find_area()<<endl;
}
We have two constructors for the class - circle(float r) and circle(float r, int cenx, int ceny)

So the names of these constructors are circle - class name. They have no return type.


And also we did not invoke these constructors explicitly. We just created the objects c1 and c2.

Passing values to constructors

If a constructor is not called explicitly, how are arguments passed to it? They are sent within parentheses after the object name - c1(7), c2(2,10,10)

 Default constructor

If a constructor takes 0 parameters or it has default values for all parameters, then it is called default constructor. 

When an object is created without sending any values, default constructor is called. It is also called when an array of objects is created.
class A
{
public:
 A()
 { 
 cout<<"constructor";
 }/*default constructor*/
 A(int m)
 {
 cout<<"parameterized constructor\n Number is "<<m;
 }
};
class B
{
public:
 B(int n=0){/*code*/} /*default ctor*/
};
int main()
{
 A obj1;/* calls default constructor*/
 A obj2(3);/*calls parameterized ctor*/
 B obj3;/* ok*/
 B obj4(10);/*ok*/
 A arr[4];/*calls default ctor 4 times*/}
ENDOFCODE

Output of the program:
def constructor of A
parameterized constructor of A
 Number is 3
Constructor of B
Constructor of B
def constructor of A
def constructor of A
def constructor of A
def constructor of A


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

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

class C
{
 int m;
public:
 void somefn();
};

Class C 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.

class A
{
public: 
 A(int m)
 {
 cout<<"para. constructor\n Number is "<<m;
 }
};
int main()
{
 A obj1(9);/*ok*/
 A obj2;/*error*/
}

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

Comment the only constructor of A class now. And observe what happens to
A obj2;
Let us revise with few questions here.

Which of the following are valid default constructors of the class Rectangle?
  1. Rectangle::Rectangle(int side=0);
  2. void Rectangle::Rectangle();
  3. Rectangle::Rectangle(int s);
  4. Rectangle::Rectangle();
Answers:

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 is invalid because constructors do not have return type. Not void also.

3 is invalid because, this constructor has one parameter.

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 like this

Number::Number(int m,int n):a(m),b(n)
{
 cout<<"Constructor";
}


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.

Member initializer can also call 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
class A
{
 int m;
 const int n;
public:
 A(int x,int y)
 {
 m = x;
 n = y;/* error. Can not modify constant data*/
 }
}

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

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

Comments

Popular posts from this blog

Find the error in C++ program

This C++ program is not compiling. What do you think is the error with the program? #include<iostream> using namespace std; int main() {    int arr[10];    arr={1,2,3,4,5,6,7,8};    cout<<"arr[0]="<<arr[0];    return 0; } Is the error due to Not using printf Initialising the array with only 8 elements instead of 10 Initialising array in the next statement instead of in definition. None of the above  Now if you like this question, there are plenty more questions like this and programs and notes in my app Simplified C++. Download the Simplif ied C++   by Hegdeapps now By the way the correct answer is (3)

Abstract class

 If we can not create any objects of a class, then it is called an abstract class. A class is made abstract by adding at least one pure virtual function to it. Pure virtual function A function is said to be a pure virtual function , if it has no definition but has only declaration. Pure virtual function is defined with the keyword virtual and followed by return type, function name and "=0". class Shape { public: virtual void printarea() =0 ; }; int main () { Shape obj1; //error } Here printarea() function of Shape class is a pure virtual function as it has no body. To make a function as pure virtual function, you should use =0 at the end of virtual function declaration Abstract class When a class has at least one pure virtual function, it is incomplete and no objects can be created from that class. Such a class is called an abstract class . In the earlier example class Shape is an abstract class, and objects can not be created from t...

Friends of C++

Friend function Remember that a member which is not public (Private and protected )  can not be accessed from outside the class.  Three are some situations where you may need to access these. Keyword friend  is used for this. A friend functions and classes can access all members of a class.  This concept is controversial. People say friend concept violates data encapsulation  A friend function is a non-member function but still can access all the members of a class including private members. Such a function is declared within class body with the prefix "friend" class Number { int num; public: Number( int m){ /*code*/ } friend void printNum(Number ob); /*friend function*/ }; void printNum (Number obj) { cout << obj.num << "endl" ; } printNum() is not member of class Number . But it can still access all members including private members, because it is a friend. Friend class An object of a friend c...