Search code examples
c++constructorprivatedefault-constructorpublic-method

Default constructor of an Empty Class is public. But how?


I have a simple question:

class my
{
};
my ob;

Compiler allows me to create an object which makes sense. And, I am aware that you can't create object where the constructor is private.

To me it looks that, everything inside the class is private but obviously not the default constructor(because it is allowing me to create the object as default constructor should be public). But what confuses me is that there is no public section in the class.

So, does it create a public section only to put a default constructor under it in this case?

Or there is something else going on and my rationale is incorrect?

Also, how are accesses public, private and protected internally organised/tracked when an object is created/accessed?

I got this question as I never created an object of an empty class until now.


Solution

  • If you do not declare any constructor yourself, C++ compilers will always generate a public trivial constructor for you. More than that even, it will also implicitly create a public copy constructor and assignment operator.

    From C++11 standard 12.1.5:

    If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted. An implicitly-declared default constructor is an inline public member of its class.

    and 12.8.7, 12.8.11:

    If the class definition does not explicitly declare a copy constructor, one is declared implicitly. [...] An implicitly-declared copy [...] constructor is an inline public member of its class.

    and finally 12.8.18, 12.8.20, 12.8.22:

    If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. [...] If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared [...]. An implicitly-declared copy/move assignment operator is an inline public member of its class.

    Note that a move assignment operator will only be generated under certain circumstances, which are beyond the scope of this question, see 12.8.20 for more details.

    If you want a private constructor you have to declare it yourself:

    class my { my() {} };
    

    If you want to prevent the generation of copy constructor or assignment operator you can either declare, but not implement them:

    class my { my(my const &); };
    

    Or, since C++11, explicitly delete them:

    class my { my(my const &) = delete; };