Решение 1
Если вы в порядке с оформленным именем, тогда вы можете написать бесплатный шаблон функции:
struct Vehicle {};
struct Aircraft : Vehicle { typedef Vehicle super; };
struct Helicopter : Aircraft { typedef Aircraft super; };
template<typename T>
string getClassLineage()
{
static string lineage = string(typeid(T).name()) +" - " + getClassLineage<typename T::super>();
return lineage;
}
template<>
string getClassLineage<Vehicle>()
{
static string lineage = string(typeid(Vehicle).name());
return lineage;
}
int main() {
cout << getClassLineage<Helicopter>() << endl;
return 0;
}
Вывод (оформленные имена):
10Вертолет - 8Aircraft - 7Техника
См. В идеоне: http://www.ideone.com/5PoJ0
Вы можете снять украшение, если хотите.Но это будет зависеть от компилятора! Здесь - это версия, которая использует функцию remove_decoration
для снятия украшения, а затем выводится:
Вертолет - Самолет - Транспортное средство
Кстати, как я уже сказал, реализация функции remove_decoration
зависит от компилятора;Кроме того, это может быть написано более корректно, поскольку я не знаю всех случаев, которые рассматривает GCC, в то время как искажает имена классов.Но я надеюсь, вы поняли основную идею.
Решение 2
Если вы согласны с переопределением функции в каждом производном классе, то вот простое решение:
struct Vehicle
{
string getClassLineage() const { return "Vehicle"; }
};
struct Aircraft : Vehicle
{
string getClassLineage() const { return Vehicle::getClassLineage()+" - Aircraft"; }
};
struct Helicopter : Aircraft
{
string getClassLineage() const { return Aircraft::getClassLineage()+" - Helicopter "; }
};
int main() {
Helicopter heli;
cout << heli.getClassLineage() << endl;
return 0;
}
Выход:
Транспортное средство - Самолет - Вертолет
См. Вывод на ideone: http://www.ideone.com/Z0Tws