Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move constructor and const member variables

I like the idea of const member variables especially when I wrap C functions into classes. The constructor takes a resource handle (e.g. a file descriptor) that stays valid during the whole object life time and the destructor finally closes it. (That is the idea behind RAII, right?)

But with the C++0x move constructor i run into a problem. Since the destructor is also called on the "unloaded" object i need to prevent the cleanup of the resource handle. Since the member variable is const i have no way to assign the value -1 or INVALID_HANDLE (or equivalent values) to indicate to the destructor that it should not do anything.

Is there a way that the destructor is not called if the state of an object was moved to another object?

Example:

class File { public:     // Kind of "named constructor" or "static factory method"     static File open(const char *fileName, const char *modes)     {         FILE *handle = fopen(fileName, modes);         return File(handle);     }  private:     FILE * const handle;  public:     File(FILE *handle) : handle(handle)     {     }      ~File()     {         fclose(handle);     }      File(File &&other) : handle(other.handle)     {         // The compiler should not call the destructor of the "other"         // object.     }      File(const File &other) = delete;     File &operator =(const File &other) = delete; }; 
like image 569
mazatwork Avatar asked Jun 11 '11 17:06

mazatwork


People also ask

What is the move constructor in C++?

A move constructor allows the resources owned by an rvalue object to be moved into an lvalue without creating its copy. An rvalue is an expression that does not have any memory address, and an lvalue is an expression with a memory address.

Is move constructor automatically generated?

No move constructor is automatically generated.

Should member variables be const?

Avoid using the const keyword with member variables of a class or struct type. For a class type, if a piece of data is not supposed to change after being initialized, enforce this by design of the public API, not via the `const` key word.


2 Answers

This is why you should not declare said member variables const. const member variables usually serve no purpose. If you don't want users to mutate the FILE*, then don't provide them with functions to do that, and if you want to stop yourself from mutating it by accident, then mark your functions const. However, do not make member variables themselves const - because then you run into fun when you start to use move or copy semantics.

like image 127
Puppy Avatar answered Sep 20 '22 18:09

Puppy


No, there is no way to do this. I would suggest that if you're really attached to the handle variable being const you should have a non-const flag member variable that indicates whether or not destruction should do anything.

like image 22
Omnifarious Avatar answered Sep 20 '22 18:09

Omnifarious