Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct use of `= delete` for methods in classes

Is the following snipplet correct for un-defining all otherwise generated methods and constructors for a class?

struct Picture {    // 'explicit': no accidental cast from string to Picture   explicit Picture(const string &filename) { /* load image from file */ }    // no accidental construction, i.e. temporaries and the like   Picture() = delete;    // no copy   Picture(const Picture&) = delete;    // no assign   Picture& operator=(const Picture&) = delete;    // no move   Picture(Picture&&) = delete;    // no move-assign   Picture& operator=(Picture&&) = delete; // return type correct? }; 

This deletes every default compiler implementation and only leaves the destructor, right? Without it the class would be (almost) unusable I guess, but I could delete it as well, correct?

Is the return type Picture& of the move-assign operator=(Picture&&) correct? Does it make a difference if I wrote Picture&& for the return type?

like image 458
towi Avatar asked Apr 16 '11 14:04

towi


People also ask

When should you use delete in C++?

When delete is used to deallocate memory for a C++ class object, the object's destructor is called before the object's memory is deallocated (if the object has a destructor). If the operand to the delete operator is a modifiable l-value, its value is undefined after the object is deleted.

What does delete mean C++?

Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression. Delete can be used by either using Delete operator or Delete [ ] operator. New operator is used for dynamic memory allocation which puts variables on heap memory.

What does use of deleted function mean?

It means the compiler should immediately stop compiling and complain "this function is deleted" once the user use such function. If you see this error, you should check the function declaration for =delete .

Will delete operator works for normal function in C++?

= delete also works with non-member functions. This is useful for preventing implicit type conversions.


2 Answers

In addition to Xeo's answer:

Yes, everything is correct. If you wanted you could eliminate all of the deleted members but the deleted copy constructor and deleted copy assignment and have the same effect:

struct Picture {  // Also ok    // 'explicit': no accidental cast from string to Picture   explicit Picture(const string &filename) { /* load image from file */ }    // no copy   Picture(const Picture&) = delete;    // no assign   Picture& operator=(const Picture&) = delete; }; 

The explicit declaration of the copy constructor inhibits the implicit generation of the default constructor, move constructor and move assignment members. Having these members explicitly deleted is a matter of taste. Some will probably see it as good documentation. Others may see it as overly verbose.

like image 65
Howard Hinnant Avatar answered Oct 03 '22 19:10

Howard Hinnant


Seems fine to me. The return value of operator= must be a normal reference, even if the object is constructed from a rvalue reference. That is because you can't just compile an lvalue (*this) to an rvalue.
And it should take that rvalue reference per non-const Picture& operator=(Picture&&). How would you move from a constant object? ;)

like image 39
Xeo Avatar answered Oct 03 '22 18:10

Xeo