C++ 管理类的聚合/合成成员之间的关系

C++ 管理类的聚合/合成成员之间的关系,c++,relationship,aggregation,composition,C++,Relationship,Aggregation,Composition,我正在使用聚合和合成为模拟创建实体 下面的C++示例: class CCar { CCar( CDriver* pDriver ) { m_pDriver = pDriver; } CDriver* m_pDriver; CEngine m_Engine; CDriverControls m_Controls; }; 在上面的例子中,一辆汽车由一个发动机和一组驾驶控制装置(按组成)组成。一辆汽车还必须有一名司机(通过聚合) 但这只能解释层次关系——

我正在使用聚合和合成为模拟创建实体

<>下面的C++示例:

class CCar
{
    CCar( CDriver* pDriver )
    { m_pDriver = pDriver; }

    CDriver* m_pDriver;

    CEngine m_Engine;

    CDriverControls m_Controls;
};
在上面的例子中,一辆汽车由一个发动机和一组驾驶控制装置(按组成)组成。一辆汽车还必须有一名司机(通过聚合)

但这只能解释层次关系——驾驶员属于汽车,发动机和控制装置也属于汽车。但这些部件也相互关联——驾驶员必须对控制装置执行操作,控制装置必须对发动机执行操作。这些关系也在多个方向上起作用-发动机可能失速并导致控制装置卡住,或者控制装置可能疯狂旋转并伤害驾驶员?如果司机不喜欢发动机的声音,就离开了汽车怎么办?这些关系是如何运作的

我正在从许多不同的对象合成许多不同的实体,这些对象通常与其他对象交互,并且对如何以设计的方式管理这些关系感兴趣

谢谢

编辑:


正如回答所建议的,管理这种情况的一种方法是将汽车指向驾驶员,并给驾驶员一个指向汽车的指针,等等。这是有意义的,并解决了这个具体示例。然而,在设计意义上,这增加了驾驶员的责任,该物体的任务是跟踪它所属的汽车,但集装箱的责任肯定是跟踪哪些物体属于一起?同样,委托CCar管理这些关系将使CCar变成一个blob。是否有专门设计的解决方案来处理这些类型的关系?

您可以将它们构建到每个类的方法中。您所描述的是每个类的行为。您的需求表明这种关系也是双向的。您的控件类将具有接受引擎参数并调用其方法的方法。发动机的转速、马力、扭矩等将受到控制装置的限制,这些限制内置在发动机中(例如,“如果转速降得太低,熄火”)


这不仅仅是作文。将行为和规则构建到方法中。这些方法可能采用表示您需要的参数。

您可能希望在汽车和驾驶员之间建立双向关联:

CCar( CDriver* pDriver ) :
     m_pDriver(pDriver)
{
    m_pDriver->SetCar(this);
}
然后,驾驶员可以通过汽车的公共界面访问汽车的成员。

问题应该是“我的应用程序是否需要这种关系?”例如,如果您正在为一个简单的驾驶游戏模拟汽车转向,您可能根本不需要担心天窗的电机。方向盘可能需要知道它已连接到车轮,但不需要反向关系


一句话——在现实世界中,一切都是相互关联的,但在我们为解决特定问题而建立的计算机模型中,它们并非如此。

强调接口而不是组合、聚合或继承可能是有用的。例如,可以编写驱动程序类,使其可以使用“方向盘”接口。当然,方向盘的实现提供了“方向盘”接口的实现。类似地,汽车提供了一个“汽车接口”,方向盘实现可以利用这个接口


您的实现可以使用组合、聚合和继承。但在这种方法中,真正驱动设计的是接口。无论您在给定实例中使用组合、聚合还是继承,都仅仅是一个实现细节。

要解决这个问题,首先必须确定每个组件的功能

综合资本分析及审查——一种存放部件和骨料的容器

CDriver—表示驱动程序的对象

CEngine-表示引擎的对象

等等

对于一个小而简单的程序,当给司机一个指向汽车的指针时,应该使用一个简化的设计

CCar( CDriver* pDriver )
{
m_pDriver = pDriver;
m_pDriver->SetCar(this);
}
对于更大的应用来说,这是不可接受的,因为CCar可能需要添加新的部件等。如果让驾驶员能够访问整个CCar,这将是一种糟糕的设计实践——在这里,驾驶员不仅可以更改方向盘,还可以更改汽车颜色等,这显然不是他们的意图

让驱动程序访问所需的位怎么样

m_pDriver->SetSteeringWheel( m_SteeringWheel );
m_pDriver->SetHandBrake( m_HandBrake );
这就解决了这个问题,现在驾驶员无法访问汽车的其他属性(如颜色)。但是,它赋予CDriver类更多的职责。当CDriver可以使用很多控件时,该类可能会变得非常大,并负责操作这些方向盘和手制动器对象。如果司机乘坐的是另一种类型的车,而这种车的控制装置与其他车不一样,该怎么办?现在,驾驶员必须弄清楚如何使用其控制装置操作车辆?额外的逻辑。额外的斑点

所有这些问题的解决方案是使用中介类(或变体)来控制驾驶员与车辆的交互方式。这可以通过两种方式之一实现,驾驶员可以有一个汽车调解人,控制驾驶员如何与汽车互动。或者,驾驶员可以为其必须处理的汽车的每个组件或集合设置一个中介。这可能是一个更好的解决方案,因为中介可以用于不同类型的汽车。中介必须能够处理组件之间的双向关系

CCar作为容器,负责维护中介体及其组件之间的关系。就应该这样

中介人负责处理组件之间的这种关系

class CMediatorDriverToSteeringWheel
{
CMediatorDriverToSteeringWheel( CDriver* pDriver, CSteeringWheel* pSteeringWheel )
{
m_pDriver = pDriver;
m_pSteeringWheel = pSteeringWheel;
m_pDriver->AddMediator(this);
m_pSteeringWheel->AddMediator(this);
}
};

... 

CCar::CCar( CDriver* pDriver )
{
m_pDriver = pDriver;
new CMediatorDriverToSteeringWheel( m_pDriver, &m_SteeringWheel );
new CMediatorDriverToHandbrake( m_pDriver, &m_HandBrake );
}

谢谢你的回复。给出的例子实际上只是一个例子(虽然可能会用一个更好的例子!),但我一直在努力