Consider I have a class wrapping a resource:
class A {
public:
A(Data data) : handle(aquire_resource(data)) {}
A(A &&temp) : handle(temp.handle) { temp.handle = 0; }
~A() { lib_destroy(handle); }
A &operator=(A &&temp);
private:
int handle;
};
This class has no copy constructor or copy assignment as the resource handle needs to be unique across all instances of the class A - we do not want the resource to be freed while some other wrapper object still knows of the handle.
Now I want to have other classes a way to take control of the resource by having member variables of the wrapper class:
class B {
public:
B(A res, Stuff stuff) : res(res), stuff(stuff) {}
private:
A res;
Stuff stuff;
};
Consider now that I need to do some preparation of that resource before acquiring it. I need a loader function to take care of some stuff and then return the resource, because the data required for the resource can come from computation or from a file for example. Thus creating a constructor for the Wrapper that takes the file would bind the implementation of the wrapper to the way the Data it needs gets parsed and prepared. I do not consider this wise. Thus the preparation of the Data happens elsewhere, for example:
A loader(std::string filename) {
//open file
Data data;
//read data from file
return A(data);
}
The problem is with the way A is structured, I can not create objects of B in the way of:
B b(loader("foo"), stuff);
because within the constructor of B, the instance of A gains an address, thus it can no longer be bound to the &&a of its move constructor or move assignment operator.
How can I still pass the resource handle around across multiple layers of function calls and constructors without implementing a copy semantic?