Tal*_*389 21 c++ oop ooad associations aggregation
我开始研究OOAD,我很难找到一个C++
即会说明如何代码示例Association
,Aggregation
并Composition
通过编程来实现.(到处都有几个帖子,但它们与C#或java有关).我确实找到了一两个例子,但它们都与我的导师的指示相冲突,我很困惑.
我的理解是:
这就是我实现它的方式:
//ASSOCIATION
class Bar
{
Baz baz;
};
class Foo
{
Bar* bar;
void setBar(Bar* _bar)
{
bar=_bar;
}
};
//AGGREGATION
class Bar
{
Baz baz;
};
class Foo
{
Bar* bar;
void setBar(Bar* _bar)
{
bar = new Bar;
bar->baz=_bar->baz;
}
};
//COMPOSTION
class Bar
{
Baz baz;
};
class Foo
{
Bar bar;
Foo(Baz baz)
{
bar.baz=baz;
}
};
Run Code Online (Sandbox Code Playgroud)
它是否正确?如果没有,那么应该怎么做呢?如果您还给我一本书中的代码参考(以便我可以与我的导师讨论),我们将不胜感激.
Chr*_*rew 16
我要忽略聚合.它不是一个非常明确定义的概念,在我看来它会导致更多的混乱而不是它的价值.组成和协会已经足够了,Craig Larman告诉我了.它可能不是您的教师所寻求的答案,但无论如何都不可能在C++中实现.
没有一种方法可以实现组合和关联.您如何实施它们将取决于您的要求,例如关系的多样性.
实现组合的最简单方法是使用一个简单的Bar
成员变量,就像你建议的那样.我要做的唯一改变是bar
在构造函数成员初始化列表中初始化:
// COMPOSITION - with simple member variable
class Foo {
private:
Bar bar;
public:
Foo(int baz) : bar(baz) {}
};
Run Code Online (Sandbox Code Playgroud)
使用构造函数初始化列表初始化成员变量通常是个好主意,它可以更快,在某些情况下像const成员变量,它是初始化它们的唯一方法.
可能还有理由使用指针实现组合.例如,Bar
可能是多态类型,并且您在编译时不知道具体类型.或者您可能希望转发声明Bar
以最小化编译依赖性(请参阅PIMPL惯用法).或者这种关系的多样性可能是1到0..1,你需要能够得到一个null Bar
.当然因为这是Composition 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)) {}
};
Run Code Online (Sandbox Code Playgroud)
我用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; }
};
Run Code Online (Sandbox Code Playgroud)
当然,你需要确信Bar
在Foo
使用它时它会活着,否则你会有一个悬垂的指针.如果生命周期Bar
不太清楚,那么a 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";
}
};
Run Code Online (Sandbox Code Playgroud)
现在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
Run Code Online (Sandbox Code Playgroud)
在某些情况下,所有权Bar
真的不明确,协会可以使用a实现,std::shared_ptr
但我认为这应该是最后的手段.
关于使用Bar
指针的深层副本实现聚合.我不会说这是一个典型的实现,但正如我所说,这取决于您的要求.您确实需要确保在析构函数中调用delete
您的bar
成员指针,Foo
否则您有内存泄漏(或使用智能指针).
归档时间: |
|
查看次数: |
23591 次 |
最近记录: |