- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我开始研究 OOAD,但我很难找到一个 C++
代码示例来说明 Association
、Aggregation
如何和 Composition
以编程方式实现。 (到处都有几篇文章,但它们与 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;
}
};
这是正确的吗?如果没有,那么应该如何做呢?如果您还可以给我引用书中的代码,将不胜感激(以便我可以与我的导师讨论)
最佳答案
我将忽略聚合。是not a very clearly defined concept在我看来,它引起的困惑多于其值(value)。组合和联想就够了,Craig Larman这么告诉我的。这可能不是您的讲师正在寻找的答案,但无论如何它不太可能在 C++ 中与 Association 有任何不同。
没有一种方法可以实现组合和关联。您如何实现它们将取决于您的要求,例如关系的多样性。
实现组合的最简单方法是使用简单的 Bar
成员变量很像你建议的。我要做的唯一更改是初始化 bar
在构造函数成员初始化列表中:
// COMPOSITION - with simple member variable
class Foo {
private:
Bar bar;
public:
Foo(int baz) : bar(baz) {}
};
使用构造函数初始化列表来初始化成员变量通常是一个好主意,它可以更快,并且在某些情况下,例如 const 成员变量,它是初始化它们的唯一方法。
使用指针实现组合也可能是有原因的。例如 Bar
可能是多态类型,您在编译时不知 Prop 体类型。或者你想转发声明Bar
最小化编译依赖(见PIMPL idiom)。或者这种关系的多重性可能是 1 到 0..1,您需要能够有一个空值 Bar
.当然因为这是作文Foo
应该拥有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::shared_ptr
如果其他对象需要 std::weak_ptr
至Bar
.
关联通常会像您所做的那样使用指针来实现:
// 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";
}
};
现在 Foo
可以使用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
来实现关联。但我认为这应该是最后的手段。
关于使用 Bar
的深层拷贝实现聚合指针。我不会说这是一个典型的实现,但正如我所说,这取决于您的要求。 您确实需要确保调用 delete
在您的 bar
Foo
中的成员指针析构函数,否则您有内存泄漏(或使用智能指针)。
关于C++ : Association, 聚合和组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25779394/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我有四个模型类: class Group :event_producer end class PersonalBlog :event_producer end class Event true
将应用程序从Rails 4.2.9升级到Rails 5.2.1。 通过大部分令人讨厌的部分,更新了依赖关系和诸如此类的东西,最终使应用程序在console中运行,现在尝试访问server上的页面。加载
我的 EntityDefinition 中有一个关联: ... class ParentEntityDefinition extends EntityDefinition { ...
我不确定为什么这个关联无效 class Tag < ActiveRecord::Base has_and_belongs_to_many :routes end class Route < Act
我有以下关联。 PropertyOwner 是一个连接模型,它属于一个属性(property),多态地属于一个所有者,在下面的例子中是一个 ForeclosureDefense。一切正常,直到我拥有
我有一份有很多发票的工作,一张发票属于一份工作。我想查询第一张发票在某个日期范围内的工作。我有这个查询: @jobs = Job.joins(:invoices). where("invoices
我有这样的关系:用户可以拥有零只或一只狗,但狗必须属于某人。 # dog.rb class Dog { joins(:dog) } # To get records without a dog,
在我的 Rails 4 应用程序中,我有以下模型: User has_many :administrations has_many :calendars, through: :administrati
我见过的所有示例,包括文档都建议按关联过滤应使用以下语法 [contrived exampled] User.findAndCountAll({ include: [ {
我有一个下拉列表(HTML 选择框),它从这个 MySQL 查询中获取值: "SELECT cdID, cdTitle FROM CD ORDER BY cdID" 然后将结果存储在关联数组中,然后将
我是 Ruby ON Rails 新手,我的应用有 3 个模型 class User < ActiveRecord::Base has_one :user_hobby has_one :user_
我有三个模型,每个模型都有以下关联: class Model1 :model1 # will this work? is there any way around this? end class
我有一个带有帖子和标签的数据库。我想找到的帖子,只包含一个标签与一个特定的TagID,根本没有其他标签。下面的代码可以工作,但它需要服务器手动过滤结果,这将使分页变得困难。有谁有可以做到这一点的直接查
任何人都知道如何避免 PLS-00312 错误? “PLS-00312:位置参数关联可能不遵循命名关联” 我得到这个是因为下面一行: AttachList=> v_est_proc_name||'_E
我有以下工厂定义。 Factory.define :status do |f| end Factory.define :my_status , :parent => :status do |f|
我有 2 个具有 1:M 关联的模型,定义如下: var inventory = sequelize.define("Inventory",{**model definition**}; var tr
假设这个模式: var user = sequelize.define('user', { username: Sequelize.STRING, email: Sequelize.S
我正在使用 Apple 的工具进行应用站点关联验证,该工具位于此处:https://search.developer.apple.com/appsearch-validation-tool 它给了我错
实体\识别 /** * @ORM\Entity * @ORM\Table(name="c_rcgntn") */ class Recognition { /** * @ORM\
我是一名优秀的程序员,十分优秀!