C ++ 11 using the delete vs private functions specifier

I am in the process of overlaying on my C ++ (like trying to break into more modern coding) and I am looking at the delete specifier. As I understand it, it is used to make sure that certain functionality cannot be defined or called. If I understand her correctly, this is primarily in the field of assignment and copying. I'm not quite sure what the difference is between using the delete specifier and just closing those functions.

For example, what is the difference between:

class Foo { private: Foo& operator(const Foo&); Foo(const Foo&); }; 

and

  class Bar { public: Bar& operator(const Bar&) = delete; Bar(const Bar&) = delete; }; 

In other words: what uses delete specifier gain? Is it just to make things look better?

+6
source share
3 answers

One obvious difference is that if you make a function private, it is still accessible from within the class and any friends.

The explicitly removed function is not used anywhere, so you just know that it has never been used without having to check its implementation.

You can make the function private and remote: then its participation in overload resolution is more consistent.

+4
source

Short answer: using a remote function makes the program poorly formed, and you are notified at compile time, it uses a function that is not defined by end in an odd error that leaves the linker.


As an example, there is a relevant part of the standard that states:

A program that refers to a remote function implicitly or explicitly, except for the declaration, is poorly formed.

Therefore, the following compiles just fine :

 struct S { void f(); }; template<typename T, void (T::*M)() = &T::f> void g() {} int main() { g<S>(); } 

So far , the code below is :

 struct S { void f() = delete; }; template<typename T, void (T::*M)() = &T::f> void g() {} int main() { g<S>(); } 

This is because in the second case, the code is poorly formed, and in any case, you have a compile-time error, regardless of whether you intend to use M or not. In the second case, you receive an error message from the linker only if you try to use it:

 template<typename T, void (T::*M)() = &T::f> void g() { T t; (t.*M)(); } 

Of course, errors during compilation prevent problems much better. The example uses public functions, but closing them does not prevent them from being used in the class in the same way. This is just a toy example to show a possible difference.

+1
source

Simpler.

Thus, your intention is clearly stated, and your compiler can directly say that "calling this function is forbidden."

Otherwise, you rely on:

  • access control (for call attempts from outside the class) or
  • the linker gives you the "undefined" link near the end of your build process. This approach is suitable for small programs where you can quickly find out what is happening, but for deep class hierarchies, where some multiple shell objects cannot be copied, but there was no delete d, debugging luck.
+1
source

Source: https://habr.com/ru/post/1015629/


All Articles