我在使用 RobotControl 类成员时遇到问题。 UML 将 RobotControl 的位置和 RangeSensor 之间的关系指定为组合。不为它们使用指针,使它们聚合?我应该如何声明 - 相对于 UML 创建这些成员,或者 UML 有误?
最佳答案
C++ 中的指针可用于聚合和组合。区别是正确的noted by Douglas ,对象的生命周期是否相互关联。换句话说:当 parent 被摧毁时, child 是否被摧毁?答案Yes 代表组合,No 代表聚合。
我们如何在 C++ 代码中区分这些情况?
C++ 中的指针可以表示另一个(动态创建的)对象的所有权,或者仅引用其他人拥有的对象。让我们展示示例中的差异。我将解释为什么指针对每种类型的关系都有用。
用指针聚合
在这种情况下,只在 class Parent
声明之前前向声明 class Child
就可以了,并且可以设置 child
成员并在 Parent
的生命周期内重新设置。
class Child;
class Parent
{
public:
Parent(Child* ch) : child(ch) {}
Parent() : child(NULL) {}
void setChild(Child* ch) { child = ch; }
private:
Child* child;
};
用指针组合
最长的示例表明我们可以使用指针动态创建和销毁 child
。 child
的生命周期与 Parent
密切相关。但是,由于指针,我们仍然可以在 Parent
的生命周期内交换 child
ren。与下面的替代方案不同,此解决方案还允许仅在头文件中转发声明 class Child
。
// --- header file
class Child;
class Parent
{
public:
Parent();
~Parent();
void renewChild();
private:
Child* child;
};
// --- source file
#include "child.h"
Parent::Parent()
: child(new Child)
{
}
Parent::~Parent()
{
delete child;
}
void Parent::renewChild()
{
delete child;
child = new Child;
}
免责声明
此示例是 Rule of three/five/zero 的主题.我有意让用户实现缺少的推荐方法,使这个答案与方言无关,并尽可能简单。
没有指针的组合
无需手动编写构造函数和析构函数,您只需在类声明中声明child
,让编译器为您完成构造和析构。只要 class Child
的构造函数不需要参数(否则您需要手动编写 class Parent
的构造函数)并且 class Child
在 class Parent
声明之前被完全声明。
#include "child.h"
class Parent
{
private:
Child child;
};
没有指针的聚合
总而言之,使用指针进行聚合的替代方法是使用引用。但是,这可以防止在 Parent
对象的生命周期内交换 child
ren。
class Child;
class Parent
{
public:
Parent(Child& ch) : child(ch) {}
private:
Child& child;
};
关于c++ - 与指针的组成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47917759/