114

When/why would I want to explicitly delete my constructor? Assuming the reason is to prevent its usage, why not just make it private?

class Foo
{ 
  public: 
    Foo() = delete; 
};
ash
  • 3,104
  • 5
  • 24
  • 33
  • 14
    It kind of goes nicely with `= default`, not even the class can use it, and I personally prefer seeing *Use of deleted function.* over *Function is private.* The former explicitly states "This is not meant to be used." If anything comes out of that, the class not being able to use it actually makes a semantical difference. – chris Dec 01 '12 at 00:03
  • 11
    Since I rarely use C++11, this is more informative to me than the OP probably even realizes. I didn't even know you *could* tag a constructor for `delete`. Both the question and Luchian's answer easily qualify as constructive. Anyone not breathing the finer points of C++ 11 but will need to soon will get something out of both. – WhozCraig Dec 01 '12 at 06:21
  • Possible duplicate of [What's the point of deleting default class constructor?](https://stackoverflow.com/questions/48664631/whats-the-point-of-deleting-default-class-constructor) – user673679 Feb 25 '18 at 16:46

3 Answers3

106

How about:

//deleted constructor
class Foo
{ 
  public: 
    Foo() = delete;     
  public:
    static void foo();
};

void Foo::foo()
{
   Foo f;    //illegal
}

versus

//private constructor
class Foo
{ 
  private: 
    Foo() {}     
  public:
    static void foo();
};

void Foo::foo()
{
   Foo f;    //legal
}

They're basically different things. private tells you that only members of the class can call that method or access that variable (or friends of course). In this case, it's legal for a static method of that class (or any other member) to call a private constructor of a class. This doesn't hold for deleted constructors.

Sample here.

Luchian Grigore
  • 245,575
  • 61
  • 446
  • 609
  • 3
    You do not need to declare Foo() at all, if you declare Foo(int). Foo() will not be generated and thus Foo f is invalid anyway. So your example does not show the case for deleted constructor. See for yourself - http://ideone.com/mogiIF – mark Dec 01 '12 at 00:17
  • 1
    @mark I wrote 2 constructors to prove the point. I'll edit so it's clear to everyone. – Luchian Grigore Dec 01 '12 at 00:31
  • 1
    I understand the difference, I just do not understand the added value of the delete statement in general and for a constructor in particular. After all, I could specify a private default constructor without the body. Then the code also fails, only during the linking. Well, I can see that delete conveys the intention more explicitly, but that's about it. – mark Dec 01 '12 at 10:54
  • 13
    @mark Yes, that would be the C++98 way of doing things. But IMHO, conveying the intention clearly is actually a very important thing in programming in general. In this case, some readers may see a private undefined constructor and assume it's accidental and just add a definition for it, especially if the definition is as trivial as a default constructor (Yes, having a comment helps, but we'd much prefer compiler-enforcement over comment-enforcement). By having our intent clearer, we also get a much better error message which says "explicitly deleted" rather than "undefined reference". – mpark Jan 05 '14 at 21:12
  • 2
    I honestly don't understand how this answers the main question. The question in the title and OP's first question in the post was: When/why would I want to explicitly delete my constructor? – Alexander Bolinsky Oct 25 '16 at 17:20
15

why explicitly delete the constructor?

Another reason:
I use delete when I want to assure that a class is called with an initializer. I consider it as a very elegant way to achieve this without runtime checks.

The C++ compiler does this check for you.

class Foo
{
   public:
       Foo() = delete;
       Foo(int bar) : m_bar(bar) {};
   private:
       int m_bar;
}

This - very simplified - code assures that there is no instantiation like this: Foo foo;

Peter VARGA
  • 4,167
  • 3
  • 33
  • 69
  • 23
    The deleted declaration is unnecessary here. It's automatically deleted with any user-provided constructor – Mike Lui Jan 15 '19 at 18:17
  • 9
    To clarify the comment by @MikeLui, the deleted declaration is unnecessary *to the compiler*. There are numerous cases when code like this should be included to declare intent *to other programmers*. – Jeff G Apr 29 '19 at 22:30
  • 1
    Along with declaring your intent, it creates an obvious place to document your reason for its deletion in the public interface, and additionally the compiler error will be something short like "use of deleted function". If `Foo` had numerous constructors, just not a default one, then `Foo foo;` would cause a much longer error listing all implicitly defined, protected and private constructors it failed to match. – sigma Dec 20 '19 at 14:12
  • 1
    I still don't get how extra line with declaration of constructor wich "= delete" keyword declares intention of "no default constructor" idea better than ... just no default constructor? Sample: I don't want to declare variable "a" in my code - what is better, to write "// int a; // no need to define variable a" or just write nothing about this variable in code? – Ezh Jul 10 '20 at 16:00
2

I've met with default ctors declared as 'deleted' in the source code of LLVM (in AlignOf.h for instance). The associated class templates are usually in a special namespace called 'llvm::detail'. The whole purpose there I think was that they considered that class only as a helper class. They never intended to instantiate them; only to use them within the context of other class templates with some metaprogramming tricks that run in compile time.

Eg. there's this AlignmentCalcImpl class template which is used only within another class template called AlignOf as a parameter for the sizeof(.) operator. That expression can be evaluated in compile time; and there's no need to instantiate the template -> so why not declare the default ctor delete to express this intention.

But it's only my assumption.

gybacsi
  • 41
  • 5