I've stumbled onto something I can't figure out, so I think I'm missing something in the greater C++ picture.
In short, my question is: how to keep a mutable, non-deletable, possibly NULL instance of an object in a class.
The longer version is:
I have the following scenario: a bunch of classes (which I can change slightly, but not thoroughly refactor), most of which need to use an object. This object, while mutable, is managed by someone else so it must not be deleted.
Some of the classes in the bunch do not need such an object - they reuse code from other classes, but through the available parameters supplied to these classes it is guaranteed that even if an object is supplied, it will not be used.
The current implementation uses a pointer-to-const-object (const Obj *). This, in turn, means all the object's methods must be const and most fields mutable. This is a messy solution since the fields declared mutable are available for inspection (so quite the opposite of the c++ lite entry here). It also only partially solves the "do-not-delete-this-here" issue (compiler does not complain but a const in front of the object is an indication).
If I used a reference to this object, I'd force some callers to create a "dummy" object and provide it to the class they are instantiating. This is also messy, besides being a waste of resources. I cannot create a global object to can stand in for a "NULL" reference due to project restrictions.
I feel that the reference is the tool I need, but I cannot refactor the classes involved to such an extent as to have the object disappear from their implementations where it is not used (it can be done, but it is not simple and it would not be fast). So I want to implement something simpler, which will just draw an alarm signal if anyone tries to misuse this object, but keeps my object mutable.
The best solution I can think of is using a const-pointer-to-object (Obj * const) - this does not make the compiler complain, but I have my mutable object and a sort-of alarm signal -through the const - in place as well.
Does anyone have a better idea ?
I've traditionally seen these kind of scenarios implemented using a shared_ptr/weak_ptr combo. See here.
The owner/deleter would get a
boost::shared_ptr<T>
Your class would get a
boost::weak_ptr<T>
To reassign the weak ptr, simply reassign the pointer:
void MyClass::Reassign(boost::weak_ptr<T> tPtr)
{
m_tPtr = tPtr;
}
To use the weak ptr, first check to see if it's still around:
void MyClass::Use()
{
boost::shared_ptr<T> m_temporarySharedPtr = m_tPtr.lock();
if (m_temporarySharedPtr)
{
//...
}
}
The weak ptr can be made "NULL" by reseting it, or assigning it to an empty shared_ptr
void MyClass::MakeNull()
{
m_tPtr.reset();
}
You can make the destructor of that object private. That will trigger compile time error on attemp to delete object. Also you should allow restcted code to delete object by using friends mechanism or member function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With