C'est un problème d'inclusion mutuelle, "Personnage.h" est inclus dans "Guerrier.h" et ce dernier est lui-même inclus dans "Personnage.h".
Lorsque tu utilise #include en C++, le pré-processeur remplace la ligne en question par le contenu du fichier à inclure. En sachant cela essaye d'imaginer ce qui se passe lorsque tu inclus personnage.h dans un fichier cpp.
D'abord il va voir que la macro PERSONNAGE_H_INCLUDED n'est pas définie dans cette unité de traduction et il va la définir, ensuite après avoir inclus iostream et string il va tomber sur la ligne "#include "Guerrier.h"", regardons ce qui se passe lorsqu'il tente d'inclure Guerrier.h :
Il va voir que la macro GUERRIER_H_INCLUDED n'est pas définie dans l'unité de traduction actuelle et la définir, après avoir inclus iostream et string il va tomber sur la ligne"#include "Personnage.h"", sauf que là il ne va rien faire car il va tomber sur la ligne "#ifndef PERSONNAGE_H_INCLUDED" et comme cette macro a déjà été définie dans cette unité de traduction, il ne va rien inclure, donc en gros à ce moment là la classe Personnage n'a encore jamais été définie.
Ensuite il inclus "Magicien.h" et après il tombe sur la ligne "class Guerrier : public Personnage" alors que la classe Personnage n'est pas définie et n'est donc pas reconnue comme un nom de classe, d'où l'erreur "expected class-name before '{' token".