在c ++中继承复合类
我打算这个问题是一个更广义的问题,与我在以下链接中发现的问题有关:
在c ++中解决涉及多重继承和复合类的设计
我正在处理与星系相关的数据集。 关于每个星系的数据将包含关于星系的太阳系,每个太阳系行星和每个行星卫星的信息。
综合要求:
仅凭这一点,我想我需要使用复合类设计,为星系,太阳系,行星和卫星创建一个类。 星系类将包含成员容器变量,其中包含指向太阳系,行星和卫星的指针,以及适合这些容器变量的成员getter和setter函数。 太阳系将有一个类似设计的成员容器变量,其中包含指向所包含的行星和卫星的指针,以及吸气器和二传手,以及行星等等。
多重继承要求:
我用于这些类的输入数据类型并不是一成不变的。 有时候我有类型1的数据,其他时间可能是类型2的数据。我对任何给定项目的不同类型的数据可能会随着时间的推移而发生变化。 为了避免有一个怪异的增长星系类,它为每个项目可用的每种非数据类型获得新的成员变量和函数,以及所有旧的(可能在当前项目中未使用的)我想打破银河系,太阳系,行星和月球分为相关类,每个类专门处理一组特定的数据。
因此,如果我考虑两种可能的数据集,data1和data2,我可以选择为每个数据集创建每个类的特定版本。
我喜欢这种方法,因为如果我有一个需要data1和data2组合的新项目,我可以为之前从两个相关类型继承的星系,solarySystem,planet和moon类创建新类。 像下面这样。
class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo { /* . . . */ };
class SolarSystemOneTwo: public SolarSystemTwo, public SolarSystemOne{ /* . . . */};
class PlanetOneTwo: public PlanetTwo, public PlanetOne{ /* . . . */ };
class MoonOneTwo: public MoonTwo, public MoonOne{ /* . . . .*/};
这使我可以访问处理data1和data2的所有可用的和方法,然后我可以进一步定义变量和方法来处理由data1和data2组合产生的新属性。
问题:
这些设计思想,复合需求和多重继承需求对我来说都是独立运作的。 但是,我真的想使用两者。 使用两者的困难在于GalaxyOne中允许访问SolarSystemOne指针的那些容器变量对GalaxyOneTwo没有用处,因为SolarSystemOne中的指针类型不允许访问SolarSystemOneTwo的成员函数。
可能的解决方案:
模板基类 - 制作一个模板基类PrimitiveGalaxy,PrimitiveSolarSystem,PrimitivePlanet,PrimitiveMoon,其中包含所有容器变量以及所有其他类继承的相关getter和setter。 这是我在上面链接中使用的方法,它的问题可以在那里找到。
虚拟基类 - 有人建议我创建一个基类,其中包含所有类型的星系,太阳系,行星和月球的所有共享函数。 这将包括相关指针的容器变量以及它们的getter和setter。 通过这样做,指针可以用来指向每种类型的基类,并且只要基类型包含所有必要的后来定义的函数的虚函数,那么我就可以避免将指针转换为更复杂的类型。
我对这种方法的关注是它不仅需要在派生类中为每个新函数编写基类中的虚函数,而且还不是每个派生类都将定义基类中的每个虚函数。
到目前为止,上述可能的解决方案是我目前理解的唯一一个足以发布的解决方案。
我想要一个允许灵活代码的解决方案,它不需要复杂的语法,也不需要每个增长和难以管理的一系列非常大的类定义。 我的项目通常包含新类型的数据,因此我希望能够轻松地为这些新数据创建新的解析器,并且能够使用Galaxy,SolarSystem,Planet和Moon类将数据包括到我的各种项目中。
我能够通过使用抽象基类来解决我的问题。 抽象基类包含我所有的容器变量和适当的getter和setter变量。 另外,抽象基类为将在任何派生类中使用的所有方法定义抽象方法。 这些方法被预处理程序指令所包围,如果还包含定义所述函数的适当头文件,则这些指令只包含那些虚函数,这将防止进一步的抽象类。
class Galaxy{
protected:
std::vector<SolarSystem*> solarSystems;
public:
void addSolarSystem(SolarSystem*);
#ifdef GALAXYONE
virtual void aGalaxyOneMethod()=0;
#endif
#ifdef GALAXYTWO
virtual void aGalaxyTwoMethod()=0;
#endif
#ifdef GALAXYONETWO
virtual void aGalaxyOneTwoMethod()=0;
#endif
enter code here
};
GalaxyOne.h
#define GALAXYONE
class GalaxyOne{
protected:
/*Private Variables for GalaxyOne*/
public:
void aGalaxyOneMethod(); //No longer abstract
};
GalaxyTwo.h
#define GALAXYTWO
class GalaxyTWO{
protected:
/*Private Variables for GalaxyTwo*/
public:
void aGalaxyTwoMethod(); //No longer abstract
};
GalaxyOneTwo.h
#define GALAXYONE
#define GALAXYTWO
#define GALAXYONETWO
class GalaxyOneTwo: virtual public GalaxyOne, virtual public GalaxyTwo{
protected:
/*Private Variables for GalaxyOneTwo*/
public:
void aGalaxyOneTwoMethod(); //No longer abstract
};
该方案允许创建GalaxyOneTwo类型的对象并将其存储在Galaxy的指针中,并且仍然可以访问相应的功能。 SolarSystems,Planets和Moons也采用了类似的策略
链接地址: http://www.djcxy.com/p/69067.html