与指针的组成
Composition with a pointer
我在使用 RobotControl class 成员时遇到问题。 UML 将 RobotControl 的位置和 RangeSensor 之间的关系指定为组合。不为它们使用指针,使它们聚合?我应该如何声明-根据UML创建这些成员,还是UML弄错了?
C++ 中的指针可用于聚合和组合。正如 所言,区别在于 object 的生命周期是否相互关联。换句话说:当 parent 被销毁时 child 是否被销毁?答案是代表组合,否代表聚合。
我们如何在 C++ 代码中区分这些情况?
C++ 中的指针可以表示另一个(动态创建的)object 的所有权,或者仅指其他人拥有的 object。让我们展示示例中的差异。我将解释为什么指针对每种类型的关系都有用。
用指针聚合
这种情况下,在class Parent
声明前只forward-declareclass Child
就可以了,child
成员可以设置,re-set声明时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。与下面的替代方案不同,此解决方案还只允许在头文件中使用 forward-declare 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 的主题。我有意让用户执行缺少的推荐方法,保持这个答案 dialect-agnostic 并尽可能简单。
没有指针的组合
无需手动编写构造函数和析构函数,您只需在class 声明中声明child
,让编译器为您完成构造和析构。只要 class Child
的构造函数不需要参数(否则你需要手动编写 class Parent
的构造函数)并且 class Child
在声明class Parent
.
#include "child.h"
class Parent
{
private:
Child child;
};
没有指针的聚合
总而言之,使用指针进行聚合的替代方法是使用引用。但是,这可以防止在 Parent
object.
的生命周期内交换 child
ren
class Child;
class Parent
{
public:
Parent(Child& ch) : child(ch) {}
private:
Child& child;
};
我在使用 RobotControl class 成员时遇到问题。 UML 将 RobotControl 的位置和 RangeSensor 之间的关系指定为组合。不为它们使用指针,使它们聚合?我应该如何声明-根据UML创建这些成员,还是UML弄错了?
C++ 中的指针可用于聚合和组合。正如
我们如何在 C++ 代码中区分这些情况?
C++ 中的指针可以表示另一个(动态创建的)object 的所有权,或者仅指其他人拥有的 object。让我们展示示例中的差异。我将解释为什么指针对每种类型的关系都有用。
用指针聚合
这种情况下,在class Parent
声明前只forward-declareclass Child
就可以了,child
成员可以设置,re-set声明时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。与下面的替代方案不同,此解决方案还只允许在头文件中使用 forward-declare 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 的主题。我有意让用户执行缺少的推荐方法,保持这个答案 dialect-agnostic 并尽可能简单。
没有指针的组合
无需手动编写构造函数和析构函数,您只需在class 声明中声明child
,让编译器为您完成构造和析构。只要 class Child
的构造函数不需要参数(否则你需要手动编写 class Parent
的构造函数)并且 class Child
在声明class Parent
.
#include "child.h"
class Parent
{
private:
Child child;
};
没有指针的聚合
总而言之,使用指针进行聚合的替代方法是使用引用。但是,这可以防止在 Parent
object.
child
ren
class Child;
class Parent
{
public:
Parent(Child& ch) : child(ch) {}
private:
Child& child;
};