The easiest way to plumb the connections is to create an intermediary class that all game objects know about, much like every program knows about the OS it's running in. This class is responsible for taking requests to create or destroy a game object and passing it onto your Main class.
This intermediate communications class can be one of several things: a singleton, static methods in the Main class, or a class that's created and whenever a game Object is created it gets a pointer. That last one is cleaner, but will add storage required for each game Object and if you have tens of thousands every little bit adds up.
For your case, a small engine, I prefer the static methods version because you don't have to store pointers and while the communications API is a singleton the class it's talking to is not. And there's a clear concept of lifetime.
The reason to separate a little class to handle communicating like this is to keep it simple for all your game Objects, and to keep your Main class from getting littered with a bunch of message logic.
Your Main class is running through all the game Objects, then when the loop is done the Main class then asks the intermediary class what it needs create and destroy and then it does.
The reason to gather up all the Object requests is that it's pretty bad to add and delete list elements while you're looping through that same list.