Are these the same *types* of objects, or are the child objects derived from the parent. Would you mind giving a code example of your problem?
One of the most common approaches actually uses a feature you thought unnecessary: To have the children simply retain a pointer to the parent. This actually solves the data integrity issue quite well. Here's an example:
Code:
#include <list>
#include <iostream>
struct child;
struct parent {
list <child*> children;
child * lookup(child * sibling)
{
for(list<child*>::iterator
it = children.begin(); it != children.end(); ++it)
if(*it == sibling)
return *it;
return 0;
}
void disown(child * bad_seed)
{
for(list<child*>::iterator
it = children.begin(); it != children.end(); ++it)
if(*it == bad_seed)
{
children.erase(it);
break;
}
}
};
struct child {
parent & father;
list <child*> siblings;
child(parent& _father):father(_father)
{
father.children.push_back(this);
}
child * lookup(child * sibling)
{
return father.lookup(sibling);
}
void on_notify(const char * message)
{
cout << "Recieved: " << message << endl;
}
void attach(child * sibling)
{
siblings.push_back(sibling);
}
void notify(const char * message)
{
child * valid;
for(list<child*>::iterator
it = siblings.begin(); it != siblings.end(); ++it)
{
valid = lookup(*it);
if(!valid)
{
it = siblings.erase(it);
if(it == siblings.end()) break;
}
else valid->on_notify(message);
}
}
};
int main()
{
parent dad;
child one(dad), two(dad), three(dad);
one.attach(&two);
two.attach(&three);
three.attach(&one);
//dad.disown(&one); // uncomment this and one less message is printed!
//dad.disown(&two); // uncomment this and one less message is printed!
//dad.disown(&three); // uncomment this and one less message is printed!
char * message = "Notification";
one.notify(message);
two.notify(message);
three.notify(message);
return cin.get();
}