delete modifier vs declaring function as private
Asked Answered
S

4

18

I read this question, but it still doesn't make a lot of sense to me. It still sounds more like a sugarcoating feature.

What's the difference between:

class A 
{
// public/private ?
    A (const A&) = delete; 
};

and

class A 
{
private:
    A (const A&); // MISSING implementation
};

Same for operator= or other functions.

Singspiel answered 17/9, 2013 at 10:55 Comment(7)
Making them private doesn't stop you (the class implementor) calling them accidentally.Repentance
@Repentance - the executable will not be built if you try to call it..Singspiel
I believe that's technically an ill-formed program with no diagnostic required. You will also get a linker error rather than a compiler error.Repentance
@Repentance - yes, you'll get a linker problem, so it will be caught while building the project/program. It's safe, the function will NOT be actually called/executed.Singspiel
@KirilKirov: it is not (necessarily) safe when building DLLs, because you have plenty of missing symbols in DLLs and only when you load them will you realize if one is (still) missing; and thus the error is caught at runtime in those cases.Plumage
@MatthieuM. - right, good point. I didn't think about that.Singspiel
@MatthieuM. I would rather not expect this for Win32 DLLs, as opposed to Posix SOs.Thacker
A
23

One difference is that =delete allows for compile-time errors while in some cases the declaration without a definition is only caught at link-time (at which the error message is typically not pointing you to the source of the problem). One such case is when you add a member function that tries to copy an instance of A. Even when it's not a member function of A, the error message about the copy-ctor being private is not as clear as using =delete.

To avoid confusion, I'd recommend you make the deleted function public as otherwise you will get additional and misleading error messages.

Aminta answered 17/9, 2013 at 10:59 Comment(3)
I'll accept this answer, as it clearly "highlights" compile/link time, BUT I'd like to add here, that without the delete modifier, the error can be caught event AT RUNTIME - see the comment below the question by @MatthieuM.Singspiel
@KirilKirov You then might consider distinguishing between load-time and run-time. Most of the problems when using DLLs/shared libraries will arise at load-time, only if you manually and dynamically load DLLs/shared libraries in your code you will have a real run-time error. The rule when developing code is: Prefer compile-time over link-time over load-time over run-time errors. The =delete allows a certain class of problems to be promoted from the lower classes to the "best" class (compiler-time error) with improved diagnostics.Aminta
Yes, I'm aware of this. I meant exactly manually loading shared libraries, with dlopen for example.Singspiel
B
12

The difference is that the purpose of the =delete code is explicit in it's purpose. Declaring functions as private / inaccessible was a trick. Although most people knew it, the error it generated was obscure (a linking/access level error instead of a semantical problem in the code - i.e. "you are using a deleted function").

Brianbriana answered 17/9, 2013 at 10:59 Comment(2)
In other words - sugarcoating? :)Singspiel
:) In other words, they transformed an awkward workaround into a feature. I wouldn't call it sugarcoating.Brianbriana
F
3

One difference is that the old-fashioned form gives undefined behaviour if the class (or a friend) tries to destroy itself. Within class members and friends, the destructor is accessible, so there is no compile-time error if it's used. Instead, you get a violation of the One Definition Rule. In practice, this will cause a link error, but formally the behaviour is undefined.

Deleting the constructor (or other function) causes a compile error if the function is needed in any circumstances; and states the intent more explicitly, allowing the compiler to give better diagnostic messages. This is especially useful when functions are implicitly deleted due to something else being deleted.

Fredelia answered 17/9, 2013 at 11:15 Comment(2)
The OP means copy constructor not destructorMasha
@ZijingWu: So he does. I'd just answered another question about destructors, and got the two muddled. It doesn't affect the answer, though.Fredelia
S
0

Another thing which hasn't been mentioned yet: when inheriting / overriding, you can't =delete a function which already has a body but you can change a public function into a private one, making it basically inaccessible from outside.

Sororicide answered 24/8, 2022 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.