Saturday, 2 March 2013

Private constructors in C++

What happens when a constructor is made private in C++?
When a constructor is made private, it means the class cannot be instantiated directly. Whenever a class is instantiated, the constructor is called, so it must be accessible to instantiate the class. But we can facilitate the instantiation of such a class by using Named Constructor Idiom. Here we use static class functions that can instantiate and return objects of that class. As we know, static member functions can be used without an object of that class. So the idea is, to get an object of this class, we call these static member functions, which internally call the private constructor and instantiate the object. Since these static functions are member functions of the class, they can access the private constructor without any problem.
 
Example:
#include <iostream>
using namespace std;
 
class A{
public:
static A static_fun(int x){
return A(x);
}
int geta(){
return a;
}
private:
int a;
A(int x){
a = x;
cout<<"Inside the constructor of A\n";
}
};
 
int main(){
A obja = A::static_fun(2);
cout<<"The value of A.a is "<< obja.geta();
}

 
Here we observe that obj of class A could be created using the static function.
 
What is the use of this?
1) To differentiate between constructors:
Consider a class called Coordinates. We could give cartesian coordinates or polar coordinates. Now, both of them have two coordinates only. So while instantiating, we give two coordinates as arguments, but how we distinguish between polar and cartesian? So, say we make the constructor private and then provide two static methods
static Coordinates polar(float r, float theta)
static Coordinates cartesian ( float x, float y).
 
Now we can use these static methods, and the class can accordingly convert the values and store in the required variables. If the class variables are x and y (cartesian) then the polar values are converted inside this static method polar and then stored.
 
2) This does not allow the class to be inherited, since derived classes need to call the constructor of the parent.