By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,897 Members | 1,969 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,897 IT Pros & Developers. It's quick & easy.

Copying and assigning of resource-owning objects

P: n/a
Say i have an object that represents or holds a resource like an open
file, a block of memory on the heap, or an openGL texture object. The
constructor acquires the resource, and the destructor releases it. I
want to implement efficient copying and assignment for this object -
the copy constructor passes on the 'handle' (file pointer, memory
pointer, or opengl texture id) to the new object, and invalidates the
old object. I guess this is how the std::auto_ptr works too. I can
come up with several ways to do this, but i'd like to see how it
usually done, since i guess this is a quite common problem and people
will undoubtedly have come up with a brilliant solution.
Possible method: Have a boolean valid flag in the object, all methods
that require the resource check this flag and report error when the
object is not valid. Destructor only releases the resource if the
object is valid. The copy constructor and assignment operator set this
flag to false in the original object and copy the handle variable
instead of initalizing their own resource. Is this The Way To Do It,
or does it have flaws?

Marijn Haverbeke
Jul 19 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
"Marijn" <ma******@hotmail.com> wrote...
Say i have an object that represents or holds a resource like an open
file, a block of memory on the heap, or an openGL texture object. The
constructor acquires the resource, and the destructor releases it. I
want to implement efficient copying and assignment for this object -
the copy constructor passes on the 'handle' (file pointer, memory
pointer, or opengl texture id) to the new object, and invalidates the
old object. I guess this is how the std::auto_ptr works too. I can
come up with several ways to do this, but i'd like to see how it
usually done, since i guess this is a quite common problem and people
will undoubtedly have come up with a brilliant solution.
Possible method: Have a boolean valid flag in the object, all methods
that require the resource check this flag and report error when the
object is not valid. Destructor only releases the resource if the
object is valid. The copy constructor and assignment operator set this
flag to false in the original object and copy the handle variable
instead of initalizing their own resource. Is this The Way To Do It,
or does it have flaws?


The matter gets a bit more complicated when you consider the need to
have temporaries of that type or const objects of that type. You
probably need to implement some kind of reference counting scheme
for that. It's not that difficult, but it's relatively tedious (to
cover all bases, mainly).

You probably don't need a boolean flag. Keep your resources pointers
and simply set them to 0 when the resource is freed or transferred to
another object. Implement the copy constructor using a non-const
reference and let the constructed object transfer the ownership from
the object from which it's being constructed:

class MyType {
...
MyType(MyType& from) : myresource(from.myresource) {
from.resourceIsTakenBy(this);
}
void resourceIsTakenBy(MyType* heir) {
myresource = 0; // any other processing? Logging?
}
};

Take a look at the implementation of different smart pointers (the
auto_ptr in your standard library, the Boost's one, whatever else
you can find on the web). Just as you've guesses, they do have all
those features: ownership and its transfer, cleaning up when dying,
some have reference counting...

Victor
Jul 19 '05 #2

P: n/a
Thanks for the reply!

"Victor Bazarov" <v.********@attAbi.com> wrote:
The matter gets a bit more complicated when you consider the need to
have temporaries of that type or const objects of that type. You
probably need to implement some kind of reference counting scheme
for that. It's not that difficult, but it's relatively tedious (to
cover all bases, mainly).
I can see the problem with const objects, but what issues can come up with
temporaries? (in the problem that led to this post i do not need consts, just
temporary objects - pushing stuff into std containers right away, as in
container.push_back(TextureObject(45)); )
I used the reference counting thing to implement a string class (yeah i know,
i like reinventing wheels), but i was aiming for a simpler, more efficient, less
error-prone approach here. I do not need multiple objects pointing at the same
resource, so i'll just cop out and use an invalidation scheme.
You probably don't need a boolean flag. Keep your resources pointers
and simply set them to 0 when the resource is freed or transferred to
another object.
Sure. I was talking about generic resource, some of which might have identi-
fiers that could be zero, but for pointer NULL works okay.
Take a look at the implementation of different smart pointers (the
auto_ptr in your standard library, the Boost's one, whatever else
you can find on the web). Just as you've guesses, they do have all
those features: ownership and its transfer, cleaning up when dying,
some have reference counting...


Good idea, i was already imitating the std::auto_ptr behaviour, but why
imitate when you can literally copy how it is done there, ha.

Marijn

Jul 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.