[C++] Pointer ownership problem

Started by
4 comments, last by ToohrVyk 15 years, 9 months ago
The problem: lets say I have 2 classes. Class-one and class-two. Class-one _dynamically_ allocates class-two. Class-one gets initialised on the stack (class-two then, lets say, gets allocated in the constructor...dynamically). Class-one's instance is passed (copied!) onto a list which keeps track of all class-one objects. Now we have 2 instances of class-one: class-one on the stack (visible to the user (programmer)) and class-one on the list (transparent to the user). Both instances have a variable which points to the same class-two instance! Class-two will thus be deleted twice, which causes a segment error. Is there a widely-used solution / work-around / code layout which would solve this problem? Should I plainly write a function called 'reallocate_dynamic_data()'? What if class-two has a dynamic instance of class-three? Wouldn't this mean a lot of reallocating in the end? Performance? What do you do to avoid this? Thanks.
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Advertisement
You can write a copy constructor for class one, which can internally decide what it wants to do about the pointer to class two.
Quote:Original post by BosskIn Soviet Russia, you STFU WITH THOSE LAME JOKES!
The issue here is a design one. You have not decided (or expressed in a clear manner) what the ownership policy is for your instance of class-two. There are basically two possible options:

  • Every instance of class-one has exclusive ownership of the corresponding instance of class-two. Therefore, to respect this ownership policy, the copy constructor of class-one will have to allocate a new instance of class-two (which will be a copy of the other), and the destructor of class-one will delete the instance. This ownership policy is represented using a boost::scoped_ptr member in class-one, though you will have to write the copy code yourself.

  • Every instance of class-one has shared ownership of an instance of class-two. Therefore, to respect this ownership policy, a smart pointer approach will be required to keep the shared instance alive for as long as an instance of class-one references it. It is usually represented as a boost::shared_ptr member in class-one.
Any time you want to clarify ownership of dynamically allocated objects (i.e. who should delete them), smart pointers are a good way to go. Something like boost::shared_ptr will count the number of references to the object and make sure its only ever deleted once.

In many cases use of such a smart pointer will make the compiler supplied copy ctor and operator= work correctly too.
[size="1"]
I think it's the exclusive one.

It's a library, so the code the user write's (allocates etc), should basically not be used immediatly (shouldn't it?), but rather be reallocated / copied. This way the user can put a copy of the current state of the object, modify it a bit (without modifying the one put away) and put it away again, the same object with a different state.

The object passed to the library (put away) should thus be copied / reallocated. But, each object can have a list of _pointers_ other objects, which are all derived from one class. Infact, one object can have an unlimited number of pointers to other objects, which can have an unlimited number of pointers to other objects aswell...so if I copy the original object, the list of pointers will need to be reallocated...heavy job :P.

The copy constructor seems like an easy solution...but wouldn't the shared_ptr library result in lazy programming work? (you don't have to watch if you delete things twice...)
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote:Original post by Decrius
The copy constructor seems like an easy solution...but wouldn't the shared_ptr library result in lazy programming work? (you don't have to watch if you delete things twice...)


"Lazy" would somehow imply that you choose not to do things which you have to do. In this particular situation, you're delegating the task to code written by other people, which is "smart".

Another possibility is to use scoped_ptr but instead of copying the class-one object, creating a default object (in the vector) with no referenced class-two instances and swapping it with the stack one. You'd get a small performance increase (although I suspect it does not matter).

This topic is closed to new replies.

Advertisement