class Resource {
Handle resource_handle;
public:
friend void swap(Resource &a, Resource &b); // swap for the partial copy/swap idiom
Resource(); // Default with uninitialized handle whose destruction is a noop
Resource(std::string location); // Construction of resource (e.g. load something from disk)
Resource(Resource &&other); // Move constructor to receive from returns of functions
Resource &operator=(Resource other); // Sawp assignment to implement copy/swap idiom
Resoruce(Resource &other) = delete; // You can not copy resources
Resource &operator=(Resource &other) = delete; // You can not copy resources
};
A class managing a handle to a resource (file handles, gpu handles, mutexes) wants to prevent that the handle of the resoruce ever gets copied so the deconstruction of the wrapper class automatically frees the resource once and only once and nothing can access the handle anymore because the lifetime of the object has ended and (hopefully) no reference or pointer to the wrapper exists anymore.
The copy/swap and rule of 5(and a half) says that usually you want to define a copy constructor / assignment operator. Copying a resource handle is explicitly unwanted. Do I understand correctly that thus just deleting any other constructor / assignment operator solves this problem (and the compiler will shout at me if I ever assign something that is not converted to a rvalue (that therefore doesn't exist anymore after the assignment is done))
This is related to this question, as the resources I want to construct are actually only constructible after the containing data structure they are a member of is already constructed, making it necessary to move resources, but not copy them.
Deleting copy constructor and copy assignment operator for a resource handle class makes perfect sense and it would produce the desired result. (Note that copy constructor and copy assignment typically take a const reference argument. It doesn't matter here because the operator is deleted, but personally I always stick to a const reference unless there is a reason to do otherwise. I find that it makes the code easier to read.)
However the “swap assignment” is problematic.
First, it wouldn't work the way it's written in your example:
This functions takes an argument by value thus creating a copy. This wouldn't compile because copy constructor is deleted.
Second, even if something like this did work it would be misleading. People usually expect the right-hand side of an assignment to remain unchanged. I suggest to replace the “swap assignment” with a swap method:
And then you can use this method to implement a non-member swap function, and it doesn't even need to be a friend function if the
swap
method is public.