我一直在努力与一段时间这个设计问题。 我会尽我所能解释什么,我试图做的和各种走近,我已经看到,我试图和原因。
我在我处理同一类型的对象反复科学的计算环境中工作。 想象其中包含太阳能系统星系,每个太阳能系统包含行星系统,并且每个行星系统包含卫星。 为此,我认为的情况为“有”的情况,因此我用组合物,得到星系访问它的太阳能系统,并且每个太阳能系统访问哪些访问它们的卫星的行星系统:每个类别为自身的类。
通常的情况是我工作中的各种问题包含不同类型的这些对象数据的情况。 而且,由于不同类型的数据变得可用,我可以做某些事与我的对象。 所以,当我有数据类型1提供给我,我创建了以下类
class GalaxyOne { /* … */ };
class SolarSystemOne { /* … */ };
class PlanetOne{ /* … */ };
class MoonOne{ /* … */ };
而当我有数据类型2提供给我,我创建
class GalaxyTwo { /* … */ };
class SolarSystemTwo { /* … */ };
class PlanetTwo{ /* … */ };
class MoonTwo{ /* … */ };
每个类的复合材料方面通过使用容器变量处理诸如包含指向包含的类矢量。 例如,每个星系类中的人们会发现。
class GalaxyTwo{ /* … */
protected:
std::vector<SolarSystemTwo*> solarSystems;
/* … */
};
困难是当我想要类合并成高阶班。
class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo{
/* Additional methods */
};
然而,这会在solarSystems矢量歧义的问题,因为GalaxyOneTwo将有来自GalaxyOne和GalaxyTwo版本的它。 此外,它继承了载体包含指向其是类型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 */
};
这种方法适用非常漂亮那些根本银河类型(GalaxyOne和GalaxyTwo)。 但是,每当我尝试创建合并的星系类型我获得各种模棱两可的。
class GalaxyOneTwo: public GalaxyOne, public GalaxyTwo, public PrimitiveGalaxy<MoonOneTwo,PlanetOneTwo,SolarSystemOneTwo>{
/* … */
};
我得到的歧义,如果我使用的,因为它被定义三次,一次通过从GalaxyOne和GalaxyTwo各继承的版本,并通过GalaxyOneTwo第三次在GalaxyOneTwo定义的任何方法中solarSystems。
我可以为特定的使用摆脱这种模棱两可的
:: PrimitiveGalaxy solarSystems
每次提及适当的矢量,但因为它需要额外的输入和语法的很多,这是不可取的。
我一直在使用每个星系类型和原始星系之间的友谊考虑,但这需要冗长的写作水平相近。
我有一个命名空间可以简化我的代码编写一种预感,但我不知道如何定义命名空间,从而为GalaxyOneTwo定义的命名空间内,要solarSystems任何称谓PrimitiveGalaxy参考:: solarSystems
编辑:
请注意,GalaxyOne和GalaxyTwo之间的唯一区别是不包含在solarSystems类的类型。 还有,因为相关的星系不同的数据每个类别的交易有许多差异。 因此,我创建不同的类将必须对这些状态变量和方法来计算和打印数据不同的状态变量,getter和setter。 solarSystems是它给我的问题特征的一个例子。因此这就是我在这里描述。 当创建GalaxyOneTwo它将使用用于GalaxyOne和GalaxyTwo相同的数据,因此我要继承他们的所有变量和方法。 而且因为数据可以以不同的方式组合,我需要创建为内GalaxyOneTwo新方法。 这些都是一些的诸多差异,导致我使用继承。 话虽这么说,它是集装箱变量允许该给我的问题组成。 在每个solarSystem类都会有类似的载体使他们能够享受自己的行星,等等等等。
编辑:
对于专门用于我的设计理念,在这里一般(相对于这个问题,强调努力解决我目前的设计尝试)问题请访问以下链接: 指导在用C创建多重继承复合类设计++
也许你可以改变数据模型的东西基于组件的实现。 每个组件都可以包含你的不同类型提到的相同的状态信息。 你可以继承虚函数
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...
然后,您可以继承不同类型的太阳能系统或星系的创建特殊情况,并填写虚函数调用
class CoolSolarSystem : public SolarSystem
{
// Special variables
// Fill in the virtual function
void sharedSolarSystemFunction();
};
然后,您可以填充不同的基本类型与指针内的容器的特殊类型。 你应该能够避免强制转换回特殊类型如果虚拟函数调用处理的足够信息。
我认为你必须有一个class Galaxy
,一个class SolarSystem
等和你GalaxyOne
, GalaxyTwo
SolarSystemOne
, SolarSystemTwo
等只能从这些类instantited不同的对象。
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);}
};
在这里,你有三个私人向量:(使用using
你把它直接入店)
std::vector<SolarSystemOne* > GalaxyOne::solarSystems;
std::vector<SolarSystemTwo* > GalaxyTwo::solarSystems;
std::vector<SolarSystemOneTwo*> solarSystems; //GalaxyOneTwo::solarSystems;
这是你需要什么? 让它保护?
你需要抽象出来的东西“一”和“二”版本之间的共同的东西转换成一组“共同”基类:
class GalaxyCommon {
// all the common stuff between GalaxyOne and GalaxyTwo including
std::vector<SolarSystemCommon *> solarSystems;
...
};
class GalaxyOne : public virtual GalaxyCommon {
// all the stuff that is unique to model One
};
class GalaxyTwo : public virtual GalaxyCommon {
// all the stuff that is unique to model Two
};
class GalaxyOneTwo : public virtual GalaxyOne, public virtual GalaxyTwo {
// should be complete
};
注意使用的virtual
-让正常多重继承要求。
所以,如果我理解你的问题的权利:
- 有几种类型,可以什么都没有在它们之间的共同所有的星系。
- 这同样适用于太阳能和行星系统。
- 你想结合这些不同类型的集合,但有充分的机会对该类型的基本方法。
这听起来像一个情况下的boost ::任何
所以,现在你的银河:
#include <list>
#include <boost/any.hpp>
typedef std::vector<boost::any> collection;
class Galaxy
{
collection SolarSystems;
public:
...methods...
};
class SolarSystem
{
collection PlanetarySystems;
public:
...methods...
};
class PlanetarySystem
{
collection Moons;
public:
...methods...
};
Ofcourse,这并没有真正做任何事情,但是允许你将它们分组。 为了做任何有用的(调用的方法),你仍然需要检测的类型,将它转换为这种类型,然后运行你需要的代码。
然而,这里做的事情让你做的是不同类型的组对象在一起,我认为这是你GalaxyOneTwo后在做什么。 下面是详细信息,你如何能做到这一点。