7

It's possible that someone has already asked about this but googling for "default", "defaulted", "explicit" and so on doesn't give good results. But anyway.

I already know there are some differences between an explicitly defined default construtor (i.e. without arguments) and an explicitly defined defaulted constructor (i.e. with the keyword default), from here: The new keyword =default in C++11

But what are the differences between an explicitly defined defaulted constructor and implicitly defined one (i.e. when the user doesn't write it at all)?

class A
{
public:
    A() = default;
    // other stuff
};

vs

class A
{
    // other stuff
};

One thing that comes to mind is that when there is a non-default constructor then the user also has to define a default constructor explicitly. But are there any other differences?

Edit: I'm mostly interested in knowing if there's any good reason to write A() = default; instead of just omitting the constructor altogether (assuming it's the only explicitly defined constructor for the class, of course).

Community
  • 1
  • 1
NPS
  • 6,003
  • 11
  • 53
  • 90
  • This is comprehensive. http://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided-default-constructor-to-default-construct-a – Bathsheba Dec 19 '16 at 09:50
  • Gooling for "C++ default" "C++ delete" "C++ explicit" gives excellent results. Did you try it? You should also go further than three Google keywords when performing your research. Read, study, understand. – Lightness Races in Orbit Dec 19 '16 at 10:17
  • 2
    @LightnessRacesinOrbit Are you for real... These were just examples, I didn't google exactly or only these 3. And while googling e.g. "C++ default" gives some good results in general, I failed to find something regarding **this exact question**. – NPS Dec 19 '16 at 10:25

2 Answers2

2

The purpose of = default is to make the implicit definition explicit. Any differences between an implicitly defined version and the explicitly defaulted version are limited to some additional possibilities appearing due to the presence of an explicit declaration.

  1. The implicitly declared/defined constructor is always public, whereas the access control of the explicitly defined defaulted constructor is under your own control.

  2. Defining a defaulted default constructor enables you annotating it with attributes. For example:

    $ cat a.cpp 
    class A
    {
    public:
        [[deprecated]] A() = default;
    };
    
    int main()
    {
        A a;
    }
    
    $ g++ -std=c++14 a.cpp
    a.cpp: In function ‘int main()’:
    a.cpp:9:7: warning: ‘constexpr A::A()’ is deprecated [-Wdeprecated-declarations]
         A a;
           ^
    a.cpp:4:20: note: declared here
         [[deprecated]] A() = default;
                        ^
    
Leon
  • 31,443
  • 4
  • 72
  • 97
  • Sure, this is a difference. Do you know of any others? – NPS Dec 19 '16 at 10:22
  • From all the differences I see it seems like the behaviour of both constructors is identical but there are differences stemming from the fact that when you write it explicitly you can do stuff to it. Correct? – NPS Dec 19 '16 at 11:38
  • @NPS Correct. I incorporated the idea of your comment in the answer. – Leon Dec 19 '16 at 11:54
1

Given below excerpt from C++ Programming Language Stroustrup 4th Edition book makes it clear that they are equivalent.


Explicit Defaults

Since the generation of otherwise default operations can be suppressed, there has to be a way of getting back a default. Also, some people prefer to see a complete list of operations in the program text even if that complete list is not needed. For example, we can write:

class gslice {
    valarray<size_t> size;
    valarray<size_t> stride;
    valarray<size_t> d1;
public:
    gslice() = default;    //<< Explicit default constructor
    ~gslice() = default;
    gslice(const gslice&) = default;
    gslice(gslice&&) = default;
    gslice& operator=(const gslice&) = default;
    gslice& operator=(gslice&&) = default;
    // ...
};

This fragment of the implementation of std::gslice (§40.5.6) is equivalent to:

class gslice {
    valarray<size_t> siz e;
    valarray<size_t> stride;
    valarray<size_t> d1;
public:
    // ...
};
Ben
  • 1,519
  • 23
  • 39
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79