Exactly what Brother Bob says; why would you allow an object to self destruct? If the enemy class had a bool collision(vec3 from_pt, vec3 to_pt) and returned true
How do you ensure that the destructor isn't called again when the object is actually about to be destroyed (for example goes out of scope, you release the memory by calling delete, or removing the object from an std::vector)?
What's wrong with having the outside logic taking care of that? If the enemy destroys itself, then that kind of implies that the enemy itself is responsible to handling the collision with projectiles. Isn't that a job for some outside component to handle collisions, like a physics component or something?
for collision, you could handle destruction just after handling the bullet physics.
To separate your subsystems collision, game logic, models etc, you'd probably want to go with those bloody iterations, flags and internal messaging systems anyways,
but it's "nicer" to delete or std::pop() / remove than it is to selfdestruct. IMO.
EDIT: Oh, I just noticed that you've taken it a few steps further. I will leave you two to it.