Guidance in creating design for multiple-inheritance composite classes in c++

纵饮孤独 提交于 2019-12-13 06:02:58

问题


I intend this question to be a more generalized question relating to my question found at the following link:

Solving design involving multiple inheritance and composite classes in c++

I am working with data sets related to Galaxies. The data about each galaxy will contain information about a galaxie's solar systems, each solar systems planets and each planets moons.

The Composite Requirement:

From this alone I imagine that I need to use composite class design where I create a class for the galaxy, the solar systems, the planets and the moons. The galaxy class will contain member container variables which contain pointers to solar systems, planets and moons in addition to the appropriate member getter and setter functions for those container variables. The solar system would have a similarly designed member container variables containing pointers to the contained planets and moons with the getters and setters, and so forth with the planets as well.

The Multiple-Inheritence Requirement:

The types of input data that I use for each of these classes is not constant. At times I have data of type 1 and other times perhaps data of type 2. The different kinds of data that I have for any given project may change as time goes on. In order to avoid having a monsterously growing galaxy class which gets new member variables and functions for each not type of data available for each project as well all of the old (and possibly unused in the current project) I want to break the galaxy, solarSystem, planet and moon classes up into related classes each specialized to deal with a certain set of data.

Thus, if I consider two of the possible data sets available to me me, data1 and data2, I may choose to create specific versions of each class for each data set.

I like this approach because if I have a new project which requires the combination of data1 and data2 I can create new classes for the galaxy, solarySystem, planet and moon classes that inherit from both of the relevent types before. Something like the following.

class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo { /* . . .  */ };
class SolarSystemOneTwo: public SolarSystemTwo, public SolarSystemOne{ /* . . . */};
class PlanetOneTwo: public PlanetTwo, public PlanetOne{ /* . . . */ };
class MoonOneTwo: public MoonTwo, public MoonOne{ /* . . . .*/};

This gives me access to all of the veriables and methods for dealing with data1 and data2 AND I can then further define variables and methods for dealing with new properties that arise out of the combination of data1 and data2.

The Problem:

Each of these design ideas, the composite requirement and the multiple-inheritence requirement have worked well on their own for me. But, I would really like to use both. The difficulty in using both is that those container variables within GalaxyOne that give it access to the pointers of SolarSystemOne are of no use to GalaxyOneTwo because the types of pointers in SolarSystemOne do not give access to the member functions of SolarSystemOneTwo.

Possible Solutions:

Template Base Class- Make a template base class PrimitiveGalaxy, PrimitiveSolarSystem, PrimitivePlanet, PrimitiveMoon which contain all of the container variables and relevant getters and setters from which all further classes inherit. This is the approach I used in the link posted above, and its problems can be found there.

Virtual Base Class- It has been proposed that I create a base class which contains all of the shared functions across all kinds of Galaxies, SolarSystems, Planets and Moons. This would include container variables to the relevant pointers as well as their getters and setters. By doing this the pointers could be used to point to the base class of each type and so long as the base type contained virtual functions for all necessary later defined functions, then I could avoid casting my pointers to the more complex types.

My concern for this approach is that it not only requires the writing of virtual functions in the base class for every new function in derived classes but also that not every derived class will define each virtual function in the base class.

Thus far, the above possible solution is the only one I currently understand well enough to post.

I want a solution that allows for flexible code that does not require complicated syntax and that does not require an every growing and unmanageable series of very large class definitions. My projects regularly include new kinds of data so I want to be able to easily create new parsers for this new data and readily be able to include the data into my various projects using the Galaxy, SolarSystem, Planet and Moon classes.


回答1:


I was able to solve my problem by using an abstract base class. The abstract base class contains all of my container variables and appropriate getter and setter variables. In addition, the abstract base class defines abstract methods for all methods that will be used in any derived class. These methods are surrounded by preprocessor directives that only include those virtual functions if the appropriate header file is also included that defines said functions, this prevents further abstract classes.

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
};

This scheme allows one to create an object of type GalaxyOneTwo and store it in a pointer of Galaxy and still have access to the appropriate functions. A similar strategy is used with SolarSystems, Planets and Moons



来源:https://stackoverflow.com/questions/15121365/guidance-in-creating-design-for-multiple-inheritance-composite-classes-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!