gpt4 book ai didi

c++ - C++中涉及多继承和复合类的解决设计

转载 作者:可可西里 更新时间:2023-11-01 18:37:55 25 4
gpt4 key购买 nike

一段时间以来,我一直在努力解决这个设计问题。我将尽我所能解释我正在尝试做什么以及我所看到的各种方法,我正在尝试什么以及为什么。

我在科学计算环境中工作,在那里我反复处理相同类型的对象。想象一个包含太阳系的星系,每个太阳系都包含行星系统,每个行星系统都包含卫星。为此,我将这种情况视为“有一个”的情况,因此我使用合成使星系可以进入其太阳系,每个太阳系都可以进入可以进入其卫星的行星系统:每个类别是它自己的类。

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

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

当我有可用的数据类型 2 时,我创建
class GalaxyTwo { /* … */ };
class SolarSystemTwo { /* … */ };
class PlanetTwo{ /* … */ };
class MoonTwo{ /* … */ };

每个类的复合方面是通过使用容器变量来处理的,例如包含指向所包含类的指针的 vector 。例如,在每个 Galaxy 类中都会找到。
class GalaxyTwo{ /* … */
protected:
std::vector<SolarSystemTwo*> solarSystems;
/* … */
};

当我想将类组合成高阶类时,困难就来了。
class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo{
/* Additional methods */
};

但是,这会在 solarSystems vector 中产生歧义问题,因为 GalaxyOneTwo 将拥有来自 GalaxyOne 和 GalaxyTwo 的版本。此外,它继承的 vector 包含指向非 SolarSystemOneTwo 类型的对象的指针,这将是必需的。所以,我想我可以创建一个模板类,我的所有对象都从我放置所有容器变量的地方继承而来。
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 */
};

这种方法非常适合那些基本的 Galaxy 类型(GalaxyOne 和 GalaxyTwo)。然而,每当我尝试创建组合星系类型时,我都会遇到各种歧义。
class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo, public     PrimitiveGalaxy<MoonOneTwo,PlanetOneTwo,SolarSystemOneTwo>{
/* … */
};

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

我可以通过具体和使用来消除这种歧义

原始星系::太阳能系统

每次都引用正确的 vector ,但这不是可取的,因为它需要大量额外的类型和语法。

我曾考虑在每个星系类型和原始星系之间使用友元,但这需要类似级别的冗长写作。

我有一种预感,命名空间可以简化我的代码编写,但我不确定如何定义命名空间,以便在为 GalaxyOneTwo 定义的命名空间中,任何对 solarSystems 的引用都是对
原始星系::太阳能系统

编辑:

请注意,GalaxyOne 和 GalaxyTwo 之间的唯一区别不是 SolarSystems 中包含的类的类型。有很多不同之处,因为每个类(class)处理与星系相关的不同数据。因此,我创建了不同的类,这些类将具有不同的状态变量、getter 和 setter,用于这些状态变量和方法来计算和打印数据。 SolarSystems 是该功能的一个示例,它给我带来了问题,因此这就是我在此处描述的内容。创建 GalaxyOneTwo 时,它将使用用于 GalaxyOne 和 GalaxyTwo 的相同数据,因此我想继承它们的所有变量和方法。由于数据可以以不同方式组合,我需要在 GalaxyOneTwo 中为此创建新方法。这些是导致我使用继承的许多差异中的一些。话虽如此,正是容器变量允许组合给我带来了问题。在每个 SolarSystem 类中,都会有一个类似的 vector ,让他们可以访问他们的行星,依此类推。

编辑:

对于一个专门针对我的一般设计理念的问题(而不是这个问题强调试图解决我当前的设计尝试),请参阅以下链接:
Guidance in creating design for multiple-inheritance composite classes in c++

最佳答案

我想你必须有一个 class Galaxy , 一 class SolarSystem等等。还有你的 GalaxyOne , GalaxyTwo SolarSystemOne , SolarSystemTwo等只是从这些类实例化的不同对象。

class SolarSystem { /* … */ };
class Planet{ /* … */ };
class Moon{ /* … */ };

class Galaxy{ /* … */
public: // Galaxy(...?...){for (...) {read data??; solarSystem.push_back(createSolarSystem(data)); }
void AddSolarSystem(SolarSystem* ss){solarSystem.push_back(ss);}
protected:
std::vector<SolarSystem*> solarSystems;
/* … */
};

....
Galaxy GalaxyOne, GalaxyTwo;

如果我们无法使用这种简单的方法......让我们看看你的:
class GalaxyOneTwo: public GalaxyOne, 
public GalaxyTwo,
public PrimitiveGalaxy<MoonOneTwo,PlanetOneTwo,SolarSystemOneTwo>{
/* … */
using PrimitiveGalaxy<MoonOneTwo,PlanetOneTwo,SolarSystemOneTwo>::solarSystems;
GalaxyOneTwo(){solarSystems.reserve(10);}
};

这里有三个私有(private) vector :(使用 using 可以直接访问)
std::vector<SolarSystemOne*   > GalaxyOne::solarSystems;
std::vector<SolarSystemTwo* > GalaxyTwo::solarSystems;
std::vector<SolarSystemOneTwo*> solarSystems; //GalaxyOneTwo::solarSystems;

这是你需要的吗?让它受到保护?
enter image description here

关于c++ - C++中涉及多继承和复合类的解决设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15075233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com