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;
}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:
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.
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
}