在C ++中反映类的继承树? [英] Reflect a class' inheritance tree in C++?

查看:110
本文介绍了在C ++中反映类的继承树?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我在C ++中有以下类,我想检查它们的继承:



车辆 / p>

汽车车辆

飞机车辆



Biplane 飞机车辆

直升机飞机车辆



我要写一个方法 getClassLineage()来执行以下操作:

  Biplane b; 
cout<< b.getClassLineage()<< endl // prints车辆 - 飞机 - 双翼飞机

直升机h;
cout<< h.getClassLineage()<< endl // prints车 - 飞机 - 直升机

汽车m;
cout<< m.getClassLineage()< endl // printsVehicle - Motorcar

似乎应该有一个简单的递归方式



假设我们愿意声明(伪代码) ) Helicopter.className =Helicopter
typedef飞机基础类 在每个派生类,但试图避免复制和粘贴 getClassLineage()

(感谢您的想法!)


解决方案

如果你想要一个类似递归的方法,你可以使用虚函数和显式的作用域函数调用:

  struct vehicle {
virtual std :: string lineage()const {returnvehicle; }
};
struct aircraft:vehicle {
typedef vehicle base;
virtual std :: string lineage()const {return base :: lineage()+--aircraft; }
};
struct biplane:aircraft {
typedef飞机基地;
virtual std :: string lineage()const {return base :: lineage()+--biplane; }
};
struct nieuport17:biplane {
typedef biplane base;
virtual std :: string lineage()const {return base :: lineage()+--nieuport17; }
};
int main(){
biplane b;
aircraft const& a = b;
std :: cout<< a.lineage()<< std :: endl;
}

它是如何工作的?当你调用 v.lineage(),因为它是一个虚拟函数,动态调度将进入 biplane :: lineage(),因为这是对象的实际类型。在这个函数里面有一个合格的调用它的父 lineage()函数。合格调用不使用动态分派机制,因此调用将实际在父级级别执行。基本上这是发生了什么:

  a.lineage() - 动态调度 - 
---> biplane :: lineage()
\__ airplane :: lineage()
\__ vehigcle :: lineage()
< - std :: string(vehicle)
< - std :: string(vehicle)+--airplane
< - std :: string(vehicle - aircraft)+--biplane
< --- std :: string(vehicle - airplane - biplane)


Say I have the following classes in C++, and I want to inspect their inheritance:

Vehicle

Motorcar is a Vehicle
Aircraft is a Vehicle

Biplane is an Aircraft is a Vehicle
Helicopter is an Aircraft is a Vehicle.

I want to write a method getClassLineage() to do the following:

Biplane b;
cout << b.getClassLineage() << endl; // prints "Vehicle--Aircraft--Biplane"

Helicopter h;
cout << h.getClassLineage() << endl; // prints "Vehicle--Aircraft--Helicopter"

Motorcar m;
cout << m.getClassLineage() << endl; // prints "Vehicle--Motorcar"

It seems like there should be a simple recursive way to do this by writing it once in the super-class, without duplicating an essentially identical method in every single one of the derived classes.

Assume we're willing to declare (pseudocode)Helicopter.className = "Helicopter" and typedef Aircraft baseclass in each of the derived classes, but trying to avoid copying and pasting getClassLineage().

Is there an elegant way to write this?

(Thank you for your thoughts!)

解决方案

If you want a recursive-like approach you can do it with virtual functions and explicit scoped function calls:

struct vehicle {
   virtual std::string lineage() const { return "vehicle"; }
};
struct aircraft : vehicle {
   typedef vehicle base;
   virtual std::string lineage() const { return base::lineage() + "--aircraft"; }
};
struct biplane : aircraft {
   typedef aircraft base;
   virtual std::string lineage() const { return base::lineage() + "--biplane"; }
};
struct nieuport17 : biplane {
   typedef biplane base;
   virtual std::string lineage() const { return base::lineage() + "--nieuport17"; }
};
int main() {
   biplane b;
   aircraft const & a = b;
   std::cout << a.lineage() << std::endl;
}

How does it work? When you call v.lineage() as it is a virtual function it the dynamic dispatch will make its way into biplane::lineage() as that is the actual type of the object. Inside that function there is a qualified call to its parent's lineage() function. Qualified calls do not use the dynamic dispatch mechanism, so the call will actually execute at the parents level. Basically this is what is going on:

a.lineage() -- dynamic dispatch -->
---> biplane::lineage() 
     \__ airplane::lineage()
         \__ vehigcle::lineage() 
          <-- std::string("vehicle")
      <-- std::string("vehicle") + "--airplane"
  <-- std::string("vehicle--airplane") + "--biplane"
<--- std::string( "vehicle--airplane--biplane" )

这篇关于在C ++中反映类的继承树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆