Why would you "default" a copy/move constructor or a destructor?
Asked Answered
B

2

7

C++0x lets you specify certain functions as defaulted:

struct A {
  A() = default;          // default ctor
  A(A const&) = default;  // copy ctor
  A(A&&) = default;       // move ctor
  A(Other);               // other ctor

  ~A() = default;         // dtor

  A& operator=(A const&) = default; // copy assignment
  A& operator=(A&&) = default;      // move assignment
};

The implementation of these functions is the same as if the compiler generated them, something that normally happens under most circumstances when you don't declare your own.

A default ctor is not generated if you declare any ctor (any of the others above), so you might need to default it to "bring it back."

However, unless a base or data member precludes them, a class always has a copy and move ctor⁠—⁠and if they are precluded, the default implementation won't work. A class always has a dtor.

Why would you need to explicitly default a copy ctor, move ctor, or destructor? Wouldn't the implicitly generated implementations do the same thing, anyway?

Berezina answered 27/9, 2010 at 14:56 Comment(5)
possible duplicate of What's the point in defaulting functions in C++0xBerezina
You posted a question, linked your own duplicate question, and then answered your own question?Embryogeny
@John: I composed the question and answer (as SO encourages from time to time) because I found this out myself (someone else asked the question on IRC, which I elaborated on above). I found the duplicate over an hour after posting—about 4 hours after I started this write-up. (No, it didn't take that long total, I didn't work straight through. ;)Berezina
Where is C++0x being discussed on IRC? (though it's probably better for my productivity if you don't answer that question)Nepil
@James: Hah! Freenode ##c++ (among other channels there, surely including ##iso-c++, though the former has a much wider topic) and EFnet #c++ (topic varies widely).Berezina
B
11

You might need to do this to change their access to non-public or to control which translation unit defines them.

Non-public

Even though these functions are commonly public, you may wish them to be non-public while still desiring the default implementation:

struct A {
protected:
  ~A();

private:
  A();
  A(A const&);
  A(A&&);
};

// according to N3092, §8.4.2/2, cannot be non-public and defaulted
// in the class definition
A::~A() = default;
A::A() = default;
A::A(A const&) = default;
A::A(A&&) = default;

This class can be default-constructed, copied, and moved, but only by methods and friends of A. This is useful for factories, where construction might be more tightly controlled.

A protected destructor is the second half of public-virtual/protected-nonvirtual guideline for base classes:

Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.

Definition control

Additionally, defaulted functions can be used to maintain a stable binary interface, since you have control over where the defaulted functions are defined. Defaulted doesn't imply inline, as the implicitly declared versions would be. (In the code above, the defaulted functions must either not be in a header or have the inline specifier added.)

Berezina answered 27/9, 2010 at 14:57 Comment(3)
Do you know what the rationale is for not allowing a non-public defaulted definition?Nepil
@James: I was wondering that myself, but I can't see a reason. The latest WD, N3126, has the same requirement. It is consistent with defaulted functions defined in the class definition being exactly like their implicitly declared counterparts, though. (Even WRT inline, since the former are defined in the class definition in that case.) However, I note 8.4.2/2 says "on its first declaration," which must be in the class definition (right?) and that seems a weird way of phrasing that.Berezina
@Roger: I do need to learn how to read question seems to be slightly different from answer :)Managua
I
2

In addition to the functional purposes, I find it useful for clarity. It makes it clear that the structure is meant to be default constructable (or whatever), and that we're using the compiler generated behavior. The more self documenting your code is, the better.

Ildaile answered 27/9, 2010 at 15:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.