Move constructor and const member variables

mazatwork picture mazatwork · Jun 11, 2011 · Viewed 9k times · Source

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;
};

Answer

Puppy picture Puppy · Jun 11, 2011

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.