Skip to content

Latest commit

 

History

History
136 lines (118 loc) · 3.21 KB

File metadata and controls

136 lines (118 loc) · 3.21 KB

= default and = delete

= default

The = default specifier indicates that the compiler should generate the default implementation for a special member function. This can be useful when you want to ensure that the default behavior is used, even if other constructors are defined.

class MyClass {
public:
  MyClass() = default; // Compiler generates the default constructor
  MyClass(int x) : value(x) { }

  int value;
};

int main() {
  MyClass obj; // Calls the default constructor
  return 0;
}

= delete

The = delete specifier is used to explicitly delete a special member function, meaning that it cannot be used. This can be helpful in preventing certain operations that would otherwise be automatically generated by the compiler.

class NonCopyable {
public:
  NonCopyable() = default; // Default constructor is fine
  NonCopyable(const NonCopyable&) = delete; // Delete copy constructor
};

int main() {
  NonCopyable obj1;
  // NonCopyable obj2 = obj1; // Error: copy constructor is deleted
  return 0;
}

In this example, the copy constructor is explicitly deleted, so attempting to copy an object of the NonCopyable class will result in a compilation error.

You can also use = delete to prevent specific overloads of a function. For example, you might want to prevent a particular constructor from being called with certain types of arguments:

Using = delete to Prohibit Specific Overloads

You can also use = delete to prevent specific overloads of a function. For example, you might want to prevent a particular constructor from being called with certain types of arguments:

class SpecificConstructor {
public:
  SpecificConstructor(double value) { }
  SpecificConstructor(int) = delete; // Delete constructor for int
};

int main() {
  SpecificConstructor obj(42.0);  // OK: double constructor
  // SpecificConstructor obj2(42); // Error: int constructor is deleted
  return 0;
}

By explicitly deleting the constructor that takes an int, you ensure that the class can only be constructed with a double.

Usage examples

struct A
{
    int x;
    A(int x = 1): x(x) {} // user-defined default constructor
};
 
struct B : A
{
    // B::B() is implicitly-defined, calls A::A()
};
 
struct C
{
    A a;
    // C::C() is implicitly-defined, calls A::A()
};
 
struct D : A
{
    D(int y) : A(y) {}
    // D::D() is not declared because another constructor exists
};
 
struct E : A
{
    E(int y) : A(y) {}
    E() = default; // explicitly defaulted, calls A::A()
};
 
struct F
{
    int& ref; // reference member
    const int c; // const member
    // F::F() is implicitly defined as deleted
};
 
// user declared copy constructor (either user-provided, deleted or defaulted)
// prevents the implicit generation of a default constructor
 
struct G
{
    G(const G&) {}
    // G::G() is implicitly defined as deleted
};
 
struct H
{
    H(const H&) = delete;
    // H::H() is implicitly defined as deleted
};
 
struct I
{
    I(const I&) = default;
    // I::I() is implicitly defined as deleted
};
 
int main()
{
    A a;
    B b;
    C c;
//  D d; // compile error
    E e;
//  F f; // compile error
//  G g; // compile error
//  H h; // compile error
//  I i; // compile error
}