Non e' cosi' semplice, anzi, tutt'altro!
Il problema principale e' la filosofia su cui le varie piattaforme sono basate, ed in particolare la parte di interfaccia grafica. Ma non solo: filesystem, ...
Filosofie diverse richiedono implementazioni diverse, ed uniformare le filosofie e' un lavoro molto arduo anche per programmatori esperti.
Quello che si deve fare, come hai detto, e' quello di creare uno strato astratto tra l'applicazione e la piattaforma (S.O.) per cui si sta' sviluppando. Ma per fare un lavoro minimamente ragionevole, e' necessario sviluppare fin da subito su piu' piattaforme contemporaneamente. Altrimenti ci si trova nella situazione che scelte fatte su una piattaforma, anche se rese astratte sono incompatibili con quelle di un'altra piattaforma.
No, un approccio piu' ragionevole, per chi e' alle prime armi (e gia' cosi' e' complicato) e' quello di avere una stessa piattaforma di sviluppo su tutti i S.O.
1) stesso compilatore
2) stesse librerie
Quind ad esempio, usando:
1) il compilatore GNU GCC (implementazione Cygwin per Windows, NON la versione mingw)
2) la libreria QT per l'interfaccia grafica (che e' multipiattaforma gia' di suo)
3) GNU Autotools (per risolvere in modo automatico tutta una serie di rognette quali, quale libreria importare per le funzioni matematiche, quale comando usare per la creazioe di directory, ...)
si e' gia' sulla buona strada per poter realizzare applicazioni che girano senza quasi modifiche su Windows, Mac OSX e Linux.
Ed anche cosi', non si eliminano situazioni strane in cui e' necessario sapere su che piattaforma dsi sta' sviluppando.
Sempre che il programma da realizzare non sia il classico "Hello World"