Let us look into some special constructors - single parameter constructor and private constructor. A single parameter constructor is used with assignment operator. And, yes, a class can have a private constructor.
Single Parameter Constructor
If a class has a constructor with only one parameter, then an assignment statement uses this constructor to convert variable of parameter type into object of the class. e.g. If a class has single integer parameter constructor, then an assignment statement assigning an integer to the object of the class uses this constructor.
Here obj1 =m is calling the constructor of Number class with one integer parameter. That is to say, the constructor is working as a conversion operator.
If you do not want assignment to implicitly call such a constructor, you can specify the keyword explicit before constructor. explicit tells the compiler that implicit conversion should not be disabled.
In the code above, the constructor is defined as explicit. So it can not be used for implicit conversion. So the statement obj1=m can not use single para. constructor and gives a compiler error.
Private Constructor
A constructor is always made public because user must be able to access it, to create and initialize an object. But what if we make the constructor private? More over, what if there is only one constructor to the class which is private? Can objects be created from this class? If yes, how?
Objects can be created from such a class using some tweaks.
Such a class must have a static object of the same class and also static public method which creates an object and returns it.
Here getInstance() calls private constructor if needed and then returns the pointer to object of class A. Also note that, the above class allows only one object to be created from the class ( such classes are called singletons)
Array of objects
We can have an array of objects in C++. Array of objects is initialized using default constructor.
If a class has no default constructor and we try to create an array of objects, then array definition throws an error.
e.g.
Number arr[3];
This creates an array arr of three Number objects. It calls default constructor of Number class thrice for creating 3 objects. But what if a class has no default constructor? In such a case there will be a compiler error.
In the above example, class A has only parameterized ctor. but no default constructor. So the array definition obj1[10] throws an error similar to one shown below.
No matching call to A::A()
But for class B, compiler provides a default constructor, as it has no user defined ctor. And array obj2 is created using compiler provided default constructor.
Array Initializers
We can also use array initializers explicitly for classes with no default constructors as in the example for class A.
Output of the program
ctor1
ctor2
ctor3
ctor4
In the code above, obj array calls parameterized constructor because there is an array initializer list provided. So obj[0] is constructed with parameter 1, obj[1] is constructed with parameter 12 etc.
This initializer can even be used with multiple parameter constructors.
C++11 features - deleted constructor and default constructor
Normally, when a class has one or more user defined constructors, then the compiler will not generate default constructor. To avoid such a behavior, in C++11, you can specify default keyword for a constructor or other special member functions. Such a declaration, makes the special member function to use the default implementation.
e.g.
class A
{
int n;
public:
A() = default;
A(int num):n(num){}
};
int main()
{
A obj1;
A obj2(10);
}
In the above example, even though, class A has one parameter constructor, the compiler generates a default constructor for the class. So the line
A obj1;
does not create an error.
Also, in C++11, you can also use delete specifier for any special member function or ordinary member function to disable calling of the function.
class B{
public:
B(int){}
B(double) = delete; // Declare the conversioin constructor as a deleted function
};
int main(){
B b1(1);
B b2(100.1); // Error, conversion from double to class B is disabled.
}
Now, as the conversion constructor from double is deleted, the compiler produces error when you try to create B object from double.