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; };
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.
No move constructor is automatically generated.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With