Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a private constructor not a private constructor?

Let's say I have a type and I want to make its default constructor private. I write the following:

class C {     C() = default; };  int main() {     C c;           // error: C::C() is private within this context (g++)                    // error: calling a private constructor of class 'C' (clang++)                    // error C2248: 'C::C' cannot access private member declared in class 'C' (MSVC)     auto c2 = C(); // error: as above } 

Great.

But then, the constructor turns out to not be as private as I thought it was:

class C {     C() = default; };  int main() {     C c{};         // OK on all compilers     auto c2 = C{}; // OK on all compilers }     

This strikes me as very surprising, unexpected, and explicitly undesired behavior. Why is this OK?

like image 310
Barry Avatar asked Jun 03 '16 15:06

Barry


People also ask

What is the correct reason for not declaring a constructor as private?

If we declare a constructor as private we are not able to create an object of a class.

When should a constructor be private?

Private constructors are used to prevent creating instances of a class when there are no instance fields or methods, such as the Math class, or when a method is called to obtain an instance of a class. If all the methods in the class are static, consider making the complete class static.

Is a constructor always private?

No, Constructors can be public , private , protected or default (no access modifier at all). Making something private doesn't mean nobody can access it. It just means that nobody outside the class can access it. So private constructor is useful too.

What is the true about private constructor?

What is true about private constructor? Explanation: Object of private constructor can only be created within class. Private constructor is used in singleton pattern.


1 Answers

The trick is in C++14 8.4.2/5 [dcl.fct.def.default]:

... A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. ...

Which means that C's default constructor is actually not user-provided, because it was explicitly defaulted on its first declaration. As such, C has no user-provided constructors and is therefore an aggregate per 8.5.1/1 [dcl.init.aggr]:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

like image 106
Angew is no longer proud of SO Avatar answered Oct 13 '22 12:10

Angew is no longer proud of SO