views:

177

answers:

2

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?

+8  A: 

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.)

Roger Pate
Do you know what the rationale is for not allowing a non-public defaulted definition?
James McNellis
@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.
Roger Pate
@Roger: I do need to learn how to read question seems to be *slightly* different from *answer* :)
David Rodríguez - dribeas
+2  A: 

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.

Dennis Zickefoose