Thursday, 13 July 2017

C++ Constructor

Constructors in C++

What is constructor?
A constructor is a member function of a class which initializes objects of a class. In C++,Constructor is automatically called when object(instance of class) create.It is special member function of the class.
How constructors are different from a normal member function?
A constructor is different from normal functions in following ways:
  • Constructor has same name as the class itself
  • Constructors don’t have return type
  • A constructor is automatically called when an object is created.
  • If we do not specify a constructor, C++ compiler generates a default constructor for us (expects no parameters and has an empty body).
Types of Constructors
  1. Default Constructors: Default constructor is the constructor which doesn’t take any argument. It has no parameters.
#include<iostream>
using namespace std;
class Point
{
private:
    int x, y;
public:
    Point(int x1, int y1) { x = x1; y = y1; }
    // Copy constructor
    Point(const Point &p2) {x = p2.x; y = p2.y; }
    int getX()            {  return x; }
    int getY()            {  return y; }
};
int main()
{
    Point p1(10, 15); // Normal constructor is called here
    Point p2 = p1; // Copy constructor is called here
    // Let us access values assigned by constructors
    cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
    cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();
    return 0;
}
  1. Output:
    a: 10  b: 20  
    Note: Even if we do not define any constructor explicitly, the compiler will automatically provide a default constructor implicitly. The default value of variables is 0 in case of automatic initialization.
  2. Parameterized Constructors: It is possible to pass arguments to constructors. Typically, these arguments help initialize an object when it is created. To create a parameterized constructor, simply add parameters to it the way you would to any other function. When you define the constructor’s body, use the parameters to initialize the object.
// CPP program to illustrate
// parameterized constructors
#include<iostream>
using namespace std;
class Point
{
    private:
        int x, y;
    public:
        // Parameterized Constructor
        Point(int x1, int y1)
        {
            x = x1;
            y = y1;
        }
     
        int getX()      
        {
            return x;
        }
        int getY()
        {
            return y;
        }
    };
int main()
{
    // Constructor called
    Point p1(10, 15);
    // Access values assigned by constructor
    cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
    return 0;
}
Output:
p1.x = 10, p1.y = 15
When an object is declared in a parameterized constructor, the initial values have to be passed as arguments to the constructor function. The normal way of object declaration may not work. The constructors can be called explicitly or implicitly.
 Example e = Example(0, 50); // Explicit call     Example e(0, 50);           // Implicit call  
Uses of Parameterized constructor:
  1. It is used to initialize the various data elements of different objects with different values when they are created.
  2. It is used to overload constructors.
Can we have more than one constructors in a class?
  1. Yes, It is called Constructor Overloading.
  2. Copy Constructor: A copy constructor is a member function which initializes an object using another object of the same class. Detailed article on Copy Constructor.

Copy Constructor in C++

We have discussed introduction to Constructors in C++. In this post, copy constructor is discussed.
What is a copy constructor? 
A copy constructor is a member function which initializes an object using another object of the same class. A copy constructor has the following general function prototype:
 ClassName (const ClassName &old_obj); 
Following is a simple example of copy constructor.
#include<iostream>
using namespace std;
class Point
{
private:
    int x, y;
public:
    Point(int x1, int y1) { x = x1; y = y1; }
    // Copy constructor
    Point(const Point &p2) {x = p2.x; y = p2.y; }
    int getX()            {  return x; }
    int getY()            {  return y; }
};
int main()
{
    Point p1(10, 15); // Normal constructor is called here
    Point p2 = p1; // Copy constructor is called here
    // Let us access values assigned by constructors
    cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
    cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();
    return 0;
}

Output:
p1.x = 10, p1.y = 15  p2.x = 10, p2.y = 15 

When is copy constructor called?
In C++, a Copy Constructor may be called in following cases:
1. When an object of the class is returned by value.
2. When an object of the class is passed (to a function) by value as an argument.
3. When an object is constructed based on another object of the same class.
4. When compiler generates a temporary object.
It is however, not guaranteed that a copy constructor will be called in all these cases, because the C++ Standard allows the compiler to optimize the copy away in certain cases
Copy constructor vs Assignment Operator
Which of the following two statements call copy constructor and which one calls assignment operator?
MyClass t1, t2;
MyClass t3 = t1;  // ----> (1)
t2 = t1;          // -----> (2)

Copy constructor is called when a new object is created from an existing object, as a copy of the existing object. Assignment operator is called when an already initialized object is assigned a new value from another existing object. In the above example (1) calls copy constrictor and (2) calls assignment operator.
Write an example class where copy constructor is needed?
Following is a complete C++ program to demonstrate use of Copy constructor. In the following String class, we must write copy constructor.
#include<iostream>
#include<cstring>
using namespace std;
class String
{
private:
    char *s;
    int size;
public:
    String(const char *str = NULL); // constructor
    ~String() { delete [] s;  }// destructor
    String(const String&); // copy constructor
    void print() { cout << s << endl; } // Function to print string
    void change(const char *);  // Function to change
};
String::String(const char *str)
{
    size = strlen(str);
    s = new char[size+1];
    strcpy(s, str);
}
void String::change(const char *str)
{
    delete [] s;
    size = strlen(str);
    s = new char[size+1];
    strcpy(s, str);
}
String::String(const String& old_str)
{
    size = old_str.size;
    s = new char[size+1];
    strcpy(s, old_str.s);
}
int main()
{
    String str1("GeeksQuiz");
    String str2 = str1;
    str1.print(); // what is printed ?
    str2.print();
    str2.change("GeeksforGeeks");
    str1.print(); // what is printed now ?
    str2.print();
    return 0;
}

Output:
GeeksQuiz  GeeksQuiz  GeeksQuiz  GeeksforGeeks
What would be the problem if we remove copy constructor from above code?
If we remove copy constructor from above program, we don’t get the expected output. The changes made to str2 reflect in str1 as well which is never expected.
#include<iostream>
#include<cstring>
using namespace std;
class String
{
private:
    char *s;
    int size;
public:
    String(const char *str = NULL); // constructor
    ~String() { delete [] s;  }// destructor
    void print() { cout << s << endl; }
    void change(const char *);  // Function to change
};
String::String(const char *str)
{
    size = strlen(str);
    s = new char[size+1];
    strcpy(s, str);
}
void String::change(const char *str)
{
    delete [] s;
    size = strlen(str);
    s = new char[size+1];
    strcpy(s, str);
}
int main()
{
    String str1("GeeksQuiz");
    String str2 = str1;
    str1.print(); // what is printed ?
    str2.print();
    str2.change("GeeksforGeeks");
    str1.print(); // what is printed now ?
    str2.print();
    return 0;
}

Output:

GeeksQuiz  GeeksQuiz  GeeksforGeeks  GeeksforGeeks

No comments:

Post a Comment

Please write your view and suggestion....