Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of `= default` allowing private constructor to be accessed

Tags:

c++

c++11

I have the code:

class Key
{
private:
    // If I use the = default keyword here, the line "Key a = {};" compiles
    // If I instead use Key() {}, that same line does not compile (as the constructor is private)
    Key() = default;

    Key(Key const &) = default;
    Key(Key &&) = default;

    Key & operator=(Key const &) = default;
    Key & operator=(Key &&) = default;
};

int main()
{
    // This line compiles when = default is used, but not when an empty constructor is used
    Key a = {};
    return 0;
}

What, specifically, is the difference between the default constructor and the empty constructor in this specific instance? Also, I would like for this to NOT compile, is explicitly writing my own empty constructor the only way to do so here? Note: This was tested with both GCC 8.3 and Clang 10.0 with identical results.

like image 332
user11923373 Avatar asked Nov 09 '20 19:11

user11923373


People also ask

How do I access a private constructor?

Class. getDeclaredConstructor() can be used to obtain the constructor object for the private constructor of the class. The parameter for this method is a Class object array that contains the formal parameter types of the constructor.

What is the use of private constructor?

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.

What happens if we declare constructor as private?

If we declare a constructor as private we are not able to create an object of a class. We can use this private constructor in the Singleton Design Pattern.

What is the purpose of private constructor in Java?

Private constructors allow us to restrict the instantiation of a class. Simply put, they prevent the creation of class instances in any place other than the class itself. Public and private constructors, used together, allow control over how we wish to instantiate our classes – this is known as constructor delegation.

Why can’t a class have a private constructor?

A class cannot be a private except inner classes because inner classes are nothing but again members of the outer class. So members of a class (field, method, constructor, and inner class) can be private but not the class itself. We can’t create subclasses to that class which has only private constructors.

What is private constructor in Java design pattern?

First thing that strikes your mind is Singleton Design Pattern which is also one of the most asked Core Java Interview Question to the 3-4 yr exp Java developers. Apart from creating singleton class, private constructor also has many other pivotal uses. With private constructor instance of that class can only be created inside declaring class.

What is the difference between Singleton and private constructor?

A singleton class is a class in Java that limits the number of objects of the declared class to one. A private constructor in Java ensures that only one object is created at a time. It restricts the class instances within the declared class so that no class instance can be created outside the declared class.

What are public and private constructors used for?

Public and private constructors, used together, allow control over how we wish to instantiate our classes – this is known as constructor delegation. 2. Typical Usage There are several patterns and benefits to restricting explicit class instantiation, and we'll go through the most common ones in this tutorial:


Video Answer


1 Answers

When default constructor is defaulted, pre C++20, this code compiles, as your class with defaulted constructor is an aggregate, and you can initialize aggregates through aggregate initialization

Key a = {}; // interpreted as aggregate initialization and bypasses access qualifier on constructor

This code would not compile in C++20 or above, as defaulted constructor makes it non-aggregate:

Key a = {}; // interpreted as calling a constructor, since Key is no longer an aggregate.

In this case compiler tries to actually call the constructor, and can't, since constructor is private.

When you have

Key() { };

Your class is no longer an aggregate in any C++ dialect, since it has a user-defined, non-defaulted constructor.

like image 191
SergeyA Avatar answered Oct 19 '22 13:10

SergeyA