Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top