object that may die anytime pointed by several objects - c++

In my game there are a lot of object of class Foo that interact with each other. A static method of the class Foo update all the object, using a container in order to track the created objects.
My problem is that a Foo object could kill another object, other instances of Foo don't know about this horrible event and they could use the dead object (deleted) anyway, thus giving an error.
I have some ideas to avoid pointer to deleted object, but I don't think they are suitable.
1) A kind of smart pointer that checks for null object.
probably this is the worse idea, I didn't not see anywhere something like this. I could create a pointer which, when delete is called, delete the pointed Foo object and then gives false when converted to Boolean (so it's possible to know if it's possible to call method on it).
2) Each Foo object doesn't track other object with a pointer but with an ID.
then the object gets a pointer to another Foo object with a static method of Foo class ( as I said Foo class has a container that tracks all the instances).
It would work also in a multithreaded environment with simple modifications, but it may be really expansive, each object searches another one in the container during each frame.
3) Each Foo object tracks objects that have a pointer to it.
The object, when killed (deleted), calls a method of the other objects. Then these object erase any pointer to the deleted object. There are other classes, too. So this isn't really object oriented.
I actually think there is an easy solution that I can't find.

Essentially all these objects share ownership of this killable object. The strongest assurance you can give them is that it won't be deleted out from under them. You can accomplish that by giving each one a boost::shared_ptr. Notifying all the objects when it dies would allow them to drop their reference. You can use boost::signals to accomplish that. I would try for this first.
If you can't do that, then you could have them store a boost::weak_ptr and when their call to boost::weak_ptr::lock failed, they would know it was dead.

Related

Managing the lifetime of member functions bound by `std::bind`

I am currently experimenting with writing an event queue in C++11. I am using std::bind to obtain std::function objects which are called when certain events happen. The code for this roughly looks like this:
class A
{
public:
void handle();
};
class B { ... };
// Later on, somewhere else...
std::vector< std::function< void() > functions;
A a;
B b;
functions.push_back( std::bind( &A::handle, &a ) );
functions.push_back( std::bind( &B::handle, &b ) );
// Even later:
for( auto&& f : functions )
f(); // <--- How do I know whether f is still "valid"?
Is there any way to guarantee the validity of the function object so that I can avoid stumbling over undefined behaviour here?
I have already taken a look at this question here, std::function to member function of object and lifetime of object, but it only discussed whether deleting a pointer to a bound object raises undefined behaviour. I am more interested in how to handle the destruction of such an object. Is there any way to detect this?
EDIT: To clarify, I know that I cannot guarantee a lifetime for non-static, non-global objects. It would be sufficient to be notified about their destruction so that the invalid function objects can be removed.
As #Joachim has stated, no lifetime is associated to the member function (it's a code section, not data). So you're asking if there is a way to know if the object still exists prior to execute the callback call.
You've to make a sort of framework, where the object dctor notify the container when it is destroyed, so the container could delete it from its "observers", the vector containing all the objects. To do that, the object must memorize in its instance the ptr to the container.
UPDATE
#Jason talks about the use of shared_ptr. It's okay to use them, but in this case, is not addressing the case of HOW to destroy the object linked in other object-notification list. Shared_ptr postponed the destruction of an instance until all "managed" references to it are deleted. But if you need to destroy object A, AND delete all reference to it because that object MUST be deleted, you've to look into all containers that store a shared_ptr and remove it. A very painful activity. The simplest solution (using raw ptr or shared_ptr, if you can use them, is irrelevant) is a two-link connection between the observer and the observed, in such way each one can notify its destruction to the other. How to store this information? many ways to accomplish it: hash tables, slots in observer, etc
One hack/workaround that achieves the desired result would be to use a parameter of type std::shared_ptr. When the bind is destructed, so is the shared pointer - which will do the right thing when it is the last reference. However this involves changes to the signature used. To make it slightly less awkward, you can use static methods that take in a std::shared_ptr this - sort of like the self parameter concept in python, if you are familiar.
Or if you are fine with C++11, you can just use a lambda capture of the shared pointer.
You'd need to dynamically allocate the instances to use this method.

How might I verify that every instance of a given class is destructed by application termination?

I wrote a simplistic DBResourceMonitor class which is used by a set of database classes. When an instance of one of my database classes is created, it registers itself, and when destroyed, it unregisters itself with a singleton instance of DBResourceMonitor. When the application terminates, that global instance of DBResrouceMonitor is destroyed, which checks to make sure that there are no remaining registered instances of any of the classes that it monitors (i.e. that for every register, a unregister was called), and issues a TRACE output and ASSERT if there was a mismatch.
This is all well and good... until I put a couple of these database objects as members of my global application object. Hence, both the global application object, and the DBResourceMonitor are global singletons, and the application is the first to be constructed, hence the last to be destroyed, and hence when DBResrouceMonitor is destroyed, the members of the app object have yet to be unregistered, and so it throws an error indicating that there were mismatched register/unregister calls.
As far as I am aware, there is no way to ensure that the DBResrouceMonitor is constructed before the application object (and therefore destroyed afterwards).
Is this correct? Is there a clever way around that, or a way to rethink the above so that I can still track whether everything was taken care of before the final thread terminates?
Instead of having the objects register/deregister themselves with a singleton, you need to store the references to those objects in a collection property of the Singleton. So instead of doing:
var x = new MyDBObject();
you would use a factory pattern like:
var x = DBResourceMonitor.GetDBObject();
and somewhere in DBResourceMonitor you could manage a collection of MyDBObjects
MyDBObject GetDBObject()
{
//construct and save a MyDBObject or retrieve one from a list.
}
You could let the database object be the same as the resource monitor, by having a base class that "registers" the database object in its constructor, and "deregister" it in the (virtual) destructor. This way you can just create the object and not worry about singletons or extra monitor classes. The collection of objects would of course be a private static member in this base class, possibly protected in case of you using multi-threading.
I would also use std::unique_ptr instead of raw pointers, or possibly std::shared_ptr.

How to pass shared_ptr to naked ptr function

I have an Entity class defined by a lib, and Registry which is class that manages Entities registered to it with a map.
What i'm trying to do:
//Registry Signature
void Registry::add(Entity* entity);
//my function (IGameEntity subclasses Entity)
void GameLogic::addEntity(shared_ptr<IGameEntity> entity, GameEntityId id) {
GameEntityId entityId = entity->getId();
gameEntities.push_back(entity);
Framework::Registry::instance()->add(entity); //<-- this doesn't work
}
I'm trying to figure how to handle this, since i'm keeping shared_ptr's and then i'm gonna have to pass a pointer.
Another thing is that if the registry gets destroyed by some reason it will call delete on all entities remaining in the map.
If i pass entity has weak_ptr<Entity>(entity) it works but i'm not fully grasping whats going on in terms of what will happen if Registry calls delete on a weak_ptr.
And if i pass entity has entity.get() what will happen when the reference count reaches zero or the registry tries to delete it.
You have two incompatible ownership schemes.
You need to either change one of them, or clone the object that should be transferred from one scheme to the other.
There is a trick for releasing a shared_ptr when there is only one reference to the object. But you don't want to do that. Even if you know enough about the insides of the library to do it.
So, as a practical solution, change the registry thing.
Make it take a shared_ptr.

C++ - Allocating on heap than using new object as reference to maintain interface

I have a case in my application where I need to create a new object dynamically based on what type info I get back from an external source. Basically, I have class A that handles this task. The class will either create class B, C, or D, etc. (say B is the base and C and D are derived types). Then I want to pass this object to an existing interface that is full of methods that expect a reference parameter of type B. Eventually this dynamically allocated object is stored in a boost::shared_ptr member object of another class (I use the reset() method on the shared_ptr). So at that point the memory is being managed by someone.
Basically it seems like this is bad design to me (that I'm passing this dynamically allocated object all over the place, dereferencing it at one point and then getting the pointer to it again later). On the other hand, I don't want to change several methods of an interface to take a pointer rather than a reference. I would like to leave that interface alone and dereference the pointer when I'm passing the object on to the interface for further processing. I read somewhere that when you have a method that takes a reference parameter, you're saying "I'm not concerned about memory management here" and "this object will be initialized - i.e. can't be NULL". The object was originally created on the heap though and will eventually be "owned" by another class that will manage its memory. Is still OK to have these interface methods take reference parameters in this case?
I think that the primary goal of design in terms of object usage and lifetime should be that the ownership of the object is clear and well-understood at all times. The creation and deletion is ideally handled in only one place, or is clearly signposted when you are creating and handing-off somewhere else - again, that should be done only in one place.
My preference would be that until the object is owned outright by some piece of code, then pointers should be used. Once it is owned, then the owner can pass it on as a reference.
With pointers, it's okay to interpret as "here's an object - does anyone want it?"
With references, you're saying "here's MY object - you can use it"
But if that forces you to makes the rest of your code ugly and confusing, then maintaining that ideal is not worth the price you pay. If you can at least make the creation and hand-off look clean, then you can hide the quirky stuff in some other (well-documented) part of the code...
B * myInst = A::BFactory( current_state_of_universe );
bool bSubmitted = SubmitForMagic( myInst );
if( !bSubmitted ) delete myInst;

questions regarding shared_from_this

I have a function which takes a shared_ptr<MyClass>.
In some member function memfun of MyClass, I need to pass this to that function. But if I write
void MyClass:memfun()
{
func(shared_ptr<MyClass>(this))
}
I am assuming that after the call has ended the reference count will reach 0 and this will be attempted to be destroyed, which is bad.
Then I remembered that there this class enable_shared_from_this with the function shared_from_this.
So now I am going to use the following:
class MyClass: public enable_shared_from_this<MyClass>
{
void MyClass:memfun()
{
func(shared_from_this());
}
};
Questions are:
1) Is is absolutely impossible to use the functionality without deriving from enable_shared_from_this?
2) Does deriving from enable_shared_from_this mean that calling memfun on an object with automatic storage duration will result in something bad? E.g.
int main()
{
MyClass m; //is this OK?
m.memfun(); // what about this?
}
3) If I derive from MyClass, will the enable_shared_from_this functionality be correctly inherited or do I need to derive again? That is,
class MyCoolClass: public Myclass
{
void someCoolMember
{
someCoolFuncTakingSharedPtrToMyCoolClass(shared_from_this());
}
}
Is this OK? Or correct is the following?
class MyCoolClass: public Myclass, public enable_shared_from_this<MyCoolClass>
{
void someCoolMember
{
someCoolFuncTakingSharedPtrToMyCoolClass(enable_shared_from_this<MyCoolClass>::shared_from_this());
}
}
Thanks very much in advance.
1) It depends on what you mean by "do this" as to whether or not you can. You can always construct a shared_ptr from a raw pointer such as this, but it won't share the reference count with another shared_ptr instance that was separately constructed from a raw pointer. You will thus need to use a custom deleter on one or other instance to avoid double deletions, but unless you take great care then you may end up with dangling shared_ptr instances due to the object being deleted through one, but still accessible from another.
shared_from_this enables you to guarantee that if you have one shared_ptr instance to your object then you can construct another without copying the first, and that these instances will share the reference count. You could achieve this by storing a weak_ptr as a class member, and setting that value when you first allocate a shared_ptr to your object.
2) Calling shared_from_this() requires that there is at least one shared_ptr instance already pointing to your object. If you use it on an automatic object without a shared_ptr instance with a custom deleter then you will get bad stuff happening.
3) If you derive from your class then the enable_shared_from_this functionality will give you a shared_ptr to the base class (the one that derived from enable_shared_from_this). You could then use static_pointer_cast or dynamic_pointer_cast to cast the result of shared_from_this() to a pointer to the derived class.
The important question here is why does the function take the argument through a shared_ptr. Does it store the pointer internally for later use? Does it only use it for the duration of the call? Why is the ownership diluted among the caller and the callee?
Some answers suggest that you provide a no-op deleter if you are going to pass a stack allocated object into the function, but if the function is actually storing the shared_ptr for later use, it might be the case that by the time it gets around to it, the locally allocated object is no longer in the stack and you trigger UB. Having the no-op deleter shared_ptr will allow the call, but the semantics will not be correct.
If the function does not store the shared_ptr for later use, what was the design decision that led to that API? If you can change the function (and there is no impending reason), make it receive the argument by reference and you will have a friendlier interface that does not impose a shared_ptr for no reason.
If at the end you determine that you can guarantee that the object in the stack will be alive for the whole duration of the process triggered by that function call, then and only then use the no-op deleter.
1) No, it's not impossible to do this without shared_from_this. You can simply construct a shared_ptr with a no-op deleter:
void do_nothing(MyClass*) {}
void MyClass:memfun()
{
func(shared_ptr<MyClass>(this, do_nothing));
}
Seeing as you don't actually seem to need shared_from_this after all, I'm going to skip the next two parts of your question.
If you have an object with automatic storage and a function that requires shared_ptr and you know that the lifetime of your object will be long enough for the duration of the function and that it does not store the shared_ptr anywhere, then you can pass it with a no-op deleter.
This is useful for static objects. If it really does have local automatic storage, you need to ask yourself why the function is taking shared_ptr. Does it store them?
There is another lesser-known constructor to shared_ptr for an object that is a member of another reference-counted object. You can actually create a shared_ptr with the shared_ptr from the outer object and the pointer from the inner object.
In addition with David Rodríguez - dribeas, shared pointer isn't recommended by google
It maintains reference count internally, so making it work correctly, InterlockedIncrement and InterlockedDecrement are used, these two functions are really slower than normal ++ and --.
You should check this object ownership truly need be shared with others, per my experience, shared pointer could be avoided in most cases.