解决涉及多个继承和在c ++中的复合类的设计 [英] Solving design involving multiple inheritance and composite classes in c++

查看:120
本文介绍了解决涉及多个继承和在c ++中的复合类的设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经努力与这个设计问题一段时间。我会尽我所能解释我正在努力做什么,以及我所看到的各种接近,我正在尝试什么,为什么。

I have struggled with this design problem for some time. I will do my best to explain what I am trying to do and the various approached that I have seen, what I am trying and why.

我在科学计算环境中工作,在那里我反复处理相同种类的对象。想象一个包含太阳能系统的星系,每个太阳系包含行星系统,每个行星系统包含卫星。为此,我认为这种情况是有的情况,因此我使用了组合来使星系进入其太阳系,每个太阳系进入能够进入其卫星的行星系统:每个类别是自己的类。

I work in a scientific computing environment where I deal with the same kinds of objects repeatedly. Imagine a galaxy which contains solar systems, each solar system contains planetary systems and each planetary system contains moons. To this end I think of the situation as a "has a" situation, and thus I have used composition to give the galaxy access to its solar systems, and each solar system access to the planetary systems which have access to their moons: each category being its own class.

通常情况下,我正在处理的各种问题包含关于这些对象的不同类型的数据。并且,随着不同类型的数据变得可用,我可以用我的对象做某些事情。所以,当我有数据类型1可用我创建以下类

It is often the case that the various problems I am working on contain different types of data about these objects. And, as different types of data become available I can do certain things with my objects. So, when I have data type 1 available to me I create the following classes

class GalaxyOne { /* … */ };
class SolarSystemOne { /* … */ };
class PlanetOne{ /* … */ };
class MoonOne{ /* … */ };

当我有数据类型2可用时,我创建

And when I have data type 2 available to me I create

class GalaxyTwo { /* … */ };
class SolarSystemTwo { /* … */ };
class PlanetTwo{ /* … */ };
class MoonTwo{ /* … */ };

每个类的复合方面通过使用容器变量来处理,例如包含指向包含类。例如,在每个Galaxy类别中,会找到一个。

The composite aspects of each class are dealt with by using container variables such as vectors which contain pointers to the contained classes. For example, within each Galaxy class one would find.

class GalaxyTwo{ /* … */
protected:
std::vector<SolarSystemTwo*> solarSystems;
/* … */
};

当我想将类组合成高阶类时,困难来了。

The difficulty comes when I want to combine classes into higher-order classes.

class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo{
/* Additional methods */
};

然而,这会在solarSystems向量中产生歧义的问题,因为GalaxyOneTwo会有一个版本GalaxyOne和GalaxyTwo。此外,它继承的向量包含指向非SolarSystemOneTwo类型的对象的指针,这将是必需的。所以,我想我可以创建一个模板类,所有的对象继承自我把所有的容器变量。

However, this creates a problem of ambiguity in the solarSystems vector because GalaxyOneTwo would have a version of it from GalaxyOne and GalaxyTwo. Furthermore, the vectors it inherits contain pointers to objects which are not of type SolarSystemOneTwo, which would be required. So, I thought I could create a template class which all of my objects inherit from where I put all of my container variables.

template<MoonT,PlanetT,SolarSystemT>
    class PrimitiveGalaxy {
    private:
        std::vector<SolarSystemT*> solarSystems
};

class GalaxyOne: public PrimitiveGalaxy <MoonOne,PlanetOne,SolarSystemOne>{
    /* No longer defining any container variables for composition */
};

这种方法非常适合那些基本的银河类型(GalaxyOne和GalaxyTwo)。

This approach works very nicely for those fundamental Galaxy types (GalaxyOne and GalaxyTwo). However, whenever I try to create the combined galaxy type I get all kinds of ambiguity.

class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo, public     PrimitiveGalaxy<MoonOneTwo,PlanetOneTwo,SolarSystemOneTwo>{
    /* … */
};

如果我在GalaxyOneTwo中定义的任何方法中使用solarSystems,我会产生歧义,因为它定义了三次,一次通过每个继承的版本从GalaxyOne和GalaxyTwo和第三次通过GalaxyOneTwo。

I get ambiguity if I use solarSystems within any method defined in GalaxyOneTwo because it is defined three times, once through each inherited version from GalaxyOne and GalaxyTwo and a third time through GalaxyOneTwo.

我可以摆脱这种歧义,具体和使用

I can get rid of this ambiguity by being specific and using

PrimitiveGalaxy :: solarSystems

PrimitiveGalaxy::solarSystems

每次引用正确的向量,但这是不可取的,因为它需要大量的额外的打字和语法。

each time to refer to the proper vector, but this is not desirable because it requires a LOT of extra typing and syntax.

我考虑过使用每个星系类型和原始星系之间的友谊,但这需要类似的详细写作水平。

I have considered using friendship between each galaxy type and the primitive galaxy but this requires a similar level of verbose writing.

我有一个希望,命名空间可以简化我的代码编写,但我不知道如何定义命名空间,以便在为GalaxyOneTwo定义的任何引用solarSystems是对
PrimitiveGalaxy :: solarSystems的引用

I have a hunch that namespaces may simplify my writing of code but I am not sure how to define the namespace such that within a namespace defined for GalaxyOneTwo that any reference to solarSystems is a reference to PrimitiveGalaxy::solarSystems

编辑:

请注意,在GalaxyOne和GalaxyTwo之间不是类中包含在solarSystems类。有很多差异,因为每个类处理与星系相关的不同数据。因此,我创建不同的类,它们将具有不同的状态变量,getter和setter用于那些状态变量和方法来计算和打印数据。太阳系是一个例子,给我的问题,因此这是我在这里描述的功能。当GalaxyOneTwo创建它将使用相同的数据,用于GalaxyOne和GalaxyTwo,因此我想继承所有的变量和方法。并且因为数据可以以不同的方式组合,我需要创建在GalaxyOneTwo中的新方法。这些是导致我使用继承的许多差异中的一些。话虽如此,它是容器变量,允许组合,给我的问题。

Please note, the only difference between GalaxyOne and GalaxyTwo is NOT the type of the class contained in solarSystems. There are many differences because each class deals with different data relevant to the galaxy. Thus, I create different classes which will have different state variables, getters and setters for those state variables and methods to calculate and print data. solarSystems is an example of the feature which is giving me problems thus that is what I have described here. When GalaxyOneTwo is created it will use the same data that is used for GalaxyOne and for GalaxyTwo and thus I want to inherit all of their variables and methods. And because the data can be combined in different ways I need to create new methods for that within GalaxyOneTwo. These are some of the many differences that lead me to use inheritance. That being said, it is the container variables that allow for composition that give me problems. Within each solarSystem class there will be a similar vector giving them access to their planets, and so on and so forth.

编辑:

对于一个专门针对我的设计哲学的问题(这个问题强调尝试解决我当前的设计尝试),请看下面的链接:
在c ++中创建多继承组合类的设计的指导

For a question specifically dedicated to my design philosophy here in general (as opposed to this questions emphasis on trying to resolve my current design attempt) see the following link: Guidance in creating design for multiple-inheritance composite classes in c++

推荐答案

也许你可以改变数据模型来实现一些基于组件。每个组件可以包含您为不同类型提到的相同的状态信息。您可以继承虚拟函数

Maybe you could change data models to implement something component based. Each component could contain the same state information you mentioned for the different types. And you could inherit virtual functions

class Galaxy
{
  // galaxy information

  // Virtual functions shared among galaxies
  virtual void sharedGalaxyFunction() = 0;

  // Vector containing all solar systems in this galaxy
  std::vector<SolarSystem*> solarSystems_;
};

class SolarSystem
{     
  // solar system info

  // Virtual functions shared among all solar systems
  virtual void sharedSolarSystemFunction() = 0;

  // Vector containing planets
  std::vector<Planets*> planets_;
};

// etc for planets...

不同类型的太阳系或星系来创建特殊情况并填写虚拟函数调用

You could then inherit the different types of solar systems or galaxies to create the special cases and fill out the virtual function calls

class CoolSolarSystem : public SolarSystem
{
  // Special variables

  // Fill in the virtual function
  void sharedSolarSystemFunction();
};

然后,您可以使用指向您的特殊类型的指针在不同基类型中填充容器。如果虚函数调用足够的信息处理,你应该能够避免转换回特殊类型。

You could then populate the containers inside the different base types with the pointers to your special types. You should be able to avoid a cast back to the special type if the virtual function calls handle enough of that information.

这篇关于解决涉及多个继承和在c ++中的复合类的设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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