Why do you want the monsters to 'recognize' each other? Not that they should or shouldn't... I'm just trying to figure out what you're trying to achieve.
Are you trying to avoid pathfinding collisions? Or should they attack, help, work together, each other?
Unfortunately ai can get pretty complicated which is why it's best to spell out the functionality that you're after and also to examine how feasible it is. Also, complicated interactions are not worth it if the player cannot detect or observe these complex interactions.
The death issue: since you're using C++, I will describe what I do. Maybe you will find it useful.
Firstly, I store a monster pool. This is an available pool of monsters whereby I can randomly select them based on certain criteria, like which level of the dungeon the player's on, the rng, etc.
Then I store a list of active monsters on the player's level. These monsters are updated each game tick with an update method and rendered, if on screen, via their render method. The list of active monsters are chosen from the monster pool when generating a new level.
For these pools, I use a std::vector of boost smart pointers. The nice thing about these smart pointers is that they garbage collect automatically. That way when they are not referenced anymore, they are cleaned up. They imo are the best tool for the job.
I then iterate over the container updating each monster and removing them from the game if applicable.
For example:
void MonsterMgr::Update()
{
for ( std::vector< boost::shared_ptr<Monster> >::iterator i = monsters[currentLevel].begin(); i != monsters[currentLevel].end(); )
{
(*i)->update();
if ( (*i)->hp <= 0.0f ) // zero hitpoints or lower, delete; monster is dead.
{
i = monsters[currentLevel].erase(i); // remove dead monster
}
else
{
++i; // Only increment the iterator if you do not delete since
// the erase method returns the next iterator.
}
}
}