* How to choose which class to make an instance of based on the object type name in the level layout file?
There are many ways to do this. First you should separate the graphical representation from the actual object. (i.e you could have four race car objects, but only one mesh that is used for all cars.) Your layout file will contain, among other things, the type of object and an identifier for the mesh(es) it uses.
Second you need to choose a paradigm to represent your objects, such as inheritance or Component Entity Systems. Simple inheritance would probably be best for now.
Now, when you load your files, you would create an object (naturally you would need if statements like you said but as things get more complicated you will look into more sophisticated patterns such as a factory method). Then you would request the mesh for this object by ID and load it if it wasn't loaded before.
* How to load and unload the graphics used by the objects in the layout?
Just like you request a mesh to be loaded, you request for it to be deleted. Mesh creation/deletion/requests can be handled by one or more classes. But for now a simple ResourceLoader class would suffice. This class would have for every mesh some kind of counter that counts how many objects are using that mesh. Every deletion request would decrement the counter until it's zero. Here you can either completely delete the mesh or keep it in cache. This depends on the type of game you're making.
* It's necessary for objects to find out about other objects of certain types for them to be able to interact.
No, they don't. Objects should NOT care about other objects. The game logic and game objects should be separated. For example, if you want to do collision between two objects, you would calculate whatever collision response you want in a different class, then tell each object to change their state or position accordingly. Direct communication between game objects should be minimal if not nonexistent.