0

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?

salbeira
  • 2,375
  • 5
  • 26
  • 40

0 Answers0