I don't understand how I can prevent accessing a dead object when it was created from a different scope and placed into some kind of container in another scope. Example
#include <iostream>
#include <string>
#include <vector>
class Foo {
public:
void Speak(){
std::cout << "ruff";
}
};
int main()
{
std::vector<Foo*> foos;
{
Foo foo;
foos.push_back(&foo);
// foo is now dead
}
for(size_t i = 0; i < foos.size(); i++){
// uh oh
foos[i]->Speak();
}
}
I have been trying for about 2 days to figure out some kind of "shared" pointer system that would wrap Foo* with another object, but no matter what, it always comes down to the fact that even that "shared" pointer won't know when Foo has died.. It's as if I am looking for a Foo destructor callback.
Notes: C++ 98, no boost.
If this has been solved 1000 times already, I would just love to know the idea behind it so I can make an interpretation of it.
Edit: To add some more context
Essentially I have this recurring problem in my designs. I really like "loose coupling" and keeping modules separate. But in order for that to happen, there must be at least one place to connect them. So I go for the pub/sub or event based systems. Therefore there must be emitters and handlers. This actually just re-wraps the problem, though. If ModuleA can emit events and ModuleB can listen to events, than ModuleA will have to have some kind of reference to ModuleB. That's not so bad, but now we have to consider all the funkiness of scope, copy ctors, = operators, etc. We have no choice but to go full out.
Example
#include <iostream>
#include <string>
class Handler {
void HandleEvent();
};
class Emitter {
public:
// add handler to some kind of container
void AttachHandler(Handler *handler);
// loop through all handlers and call HandleEvent
void EmitEvent();
};
int main()
{
// scope A
Emitter emitter;
// scope B
{
Handler handler;
emitter.AttachHandler(handler);
}
// rats..
emitter.EmitEvent();
}
Things get worse if we had something called MyObject that contains a component with an EventEmitter of its own that we want to listen to (maybe a socket). If MyObject is copied around, now we have this internal EventEmitter with handlers that reference MyObject that may no longer exist!
So maybe I dump it all and switch to callbacks.. But even then, some object is still owning ptrs or references to some other object that may no longer exist! We can be as careful as we want but we never know what's going to happen...
You know, I think what I need is to say this
- No object should ever have a reference or ptr to another object ever, unless it created that object on its own.
Now linking objects together must be done through some higher level object that manages both of those objects...
...I should have stuck to graphic design.