我开始研究 OOAD,我很难找到一个 C
代码示例来说明如何以编程方式实现关联
、聚合
和组合
。(到处都有几篇文章,但它们与 C# 或 Java 有关)。我确实找到了一两个例子,但它们都与我的导师的指示相冲突,我很困惑。
我的理解是,在:
这就是我如何实现它的:
class Bar
{
Baz baz;
};
//ASSOCIATION (with Bar)
class Foo
{
Bar* bar;
void setBar(Bar* _bar)
{
bar = _bar;
}
};
//AGGREGATION (with Bar)
class Foo
{
Bar* bar;
void setBar(Bar* _bar)
{
bar = new Bar;
bar->baz = _bar->baz;
}
};
//COMPOSTION (with Bar)
class Foo
{
Bar bar;
Foo(Baz baz)
{
bar.baz = baz;
}
};
这是对的吗?如果没有,那么应该如何做呢?如果您还给我一本书中的代码参考,我将不胜感激(以便我可以与我的老师讨论)
我将忽略聚合。它不是一个非常明确定义的概念,在我看来,它造成的混乱超过了它的价值。组合和关联就足够了,克雷格·拉曼告诉我。这可能不是你的老师想要的答案,但无论如何,它不太可能在C中实现,与关联有任何不同。
没有一种方法可以实现组合和关联。如何实现它们将取决于您的需求,例如关系的多样性。
实现组合的最简单方法是使用一个简单的Bar
成员变量,就像您建议的那样。我要做的唯一更改是初始化构造函数成员初始化器列表中的bar
:
// COMPOSITION - with simple member variable
class Foo {
private:
Bar bar;
public:
Foo(int baz) : bar(baz) {}
};
使用构造函数初始化列表来初始化成员变量通常是一个好主意,这样会更快,而且在某些情况下,像const成员变量,这是初始化它们的唯一方法。
使用指针实现复合可能也是有原因的。例如,<code>Bar</code>可能是一个多态类型,而您在编译时不知道具体的类型。或者,您可能希望转发声明<code>Bar</code>以最小化编译依赖性(请参见PIMPL习惯用法)。或者这个关系的多重性是1到0..1,你需要有一个空的<code>Bar</code>。当然,因为这是CompositionFoo
应该拥有Bar
,而在现代C 11/C 14世界中,我们更喜欢使用智能指针,而不是拥有原始指针:
// COMPOSITION - with unique_ptr
class Foo {
private:
std::unique_ptr<Bar> bar;
public:
Foo(int baz) : bar(barFactory(baz)) {}
};
我在这里使用了std::unique_ptr
,因为Foo
是Bar
的唯一所有者,但如果其他对象需要std::weak_ptr
到Bar
时,您可能需要使用td::shared_ptr
。
关联通常使用指针实现,就像您所做的那样:
// Association - with non-owning raw pointer
class Foo {
private:
Bar* bar;
public:
void setBar(Bar* b) { bar = b; }
};
当然,您需要确信Bar
在Foo
使用时会活着,否则您就有一个悬空指针。如果Bar
的生命周期不太清楚,那么std::weak_ptr
可能更合适:
// Association - with weak pointer
class Foo {
private:
std::weak_ptr<Bar> bar;
public:
void setBar(std::weak_ptr<Bar> b) { bar = std::move(b); }
void useBar() {
auto b = bar.lock();
if (b)
std::cout << b->baz << "\n";
}
};
现在< code>Foo可以使用< code>Bar而不用担心会留下悬空指针:
Foo foo;
{
auto bar = std::make_shared<Bar>(3);
foo.setBar(bar);
foo.useBar(); // ok
}
foo.useBar(); // bar has gone but it is ok
在某些情况下,Bar
的所有权确实不清楚,可以使用std::shared_ptr
实现关联,但我认为这应该是最后的手段。
关于您使用柱线
指针的深层副本实现聚合。我不会说这是一个典型的实现,但正如我所说,这取决于您的要求。您确实需要确保在 Foo
析构函数中对酒吧
成员指针调用 delete
,否则会出现内存泄漏(或使用智能指针)。
我试图确认我对关联、聚合的代码外观的理解 聚合:哈斯-a。它具有另一种类型的现有对象 组成:由另一个对象组成 协会:我对此有两种看法。 > 当一个类与另一个类相关联时。因此,上述两个都是关联的示例。 关联是一种较弱的聚合形式,其中类不保留对其接收的对象的引用。 我的理解正确吗?我在这里和这里阅读了相互矛盾的文章,所以我真的不确定该遵循哪一个。我的理解似乎符合第一个环节。我觉得第二个环节是错误的,或
我理解聚合和组合之间的区别,但我在联想方面有点挣扎。我目前的理解是,当“它们相互使用”时,类之间存在关联,例如,在方法调用期间将一个对象传递给另一个对象。另请参阅: http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit 这两个对象都是独立存在的,和聚合不同,任何对象
问题内容: 我试图理解这些术语的含义。我举了一些例子,例如: 汇总:Facebook 有一个 用户 组成:facebook 中的 每个用户 都有一个 会话。 协会:人们 使用 浏览器 但是我对 具有 和 使用我的 示例感到困惑。为什么不能是用户 使用 Facebook帐户或Facebook 使用 会话来认证用户? 就OOP而言,这是错误的吗?我在哪里想念这个概念? 问题答案: 该 使用 关系意味着
我在Stackoverflow上看到了很多解释关系区别的帖子:关联、聚合、组合和继承,并附有例子。然而,更具体地说,我对每种方法的优点和缺点,以及什么时候一种方法对手头的任务最有效感到困惑。这是我一直无法找到一个好答案的事情。 为了与论坛的指导方针保持一致,我没有问为什么人们个人更喜欢使用继承而不是组合。我特别感兴趣的是每种方法中的任何客观优点/缺点,尽管听起来很强。一、 e.一种方法是创建比另一
因此,我对UML图中的关联、聚合和组合有一些疑问。以下是一些场景: > 产品评审对产品评审的评级组成。这意味着对于每一个产品评审等级必须有产品评审?如果产品评审不存在,评审评级就没有意义。 客户NRIC协助推车和订货。我们不能使用聚合,因为如果客户不存在,购物车和订单也不存在。 有人能帮我检查一下我的关系是否正确吗?因为我对聚合和关联有点困惑,所以用关联来链接所有的表是好的吗。我不知道什么时候该用
我在UML中遇到了和关系的一些问题,我确实理解整体/部分关系,所以如果一个类不能没有它的整体而存在,那么它就成为一个强的组合关系,如果它仍然可以没有它的整体而存在,那么它就成为一个弱的聚合关系。 然而,当处理真正的软件需求时,有时会变得更加棘手。我有一个下面的类图,包括所有必要的属性、操作和特性,它们都正确地显示在UML标准中,但是我不确定我的关系: 1 接口和 6 类 有人可以确认我的关系是否正