我有两个类似于以下的类。
class Hand
{
public:
func1();
func2();
...
func20();
private:
Hand();
~Hand();
Hand(const Hand& that);
void operator=(Hand const&);
friend class Body;
};
class Body
{
public:
Body();
~Body();
Hand * const &left_hand;
Hand * const &right_hand;
private:
Hand * _left_hand;
Hand * _right_hand;
};
Body::Body()
:left_hand(_left_hand)
:right_hand(_right_hand)
{
_left_hand = new Hand();
_right_hand = new Hand();
};
这遵循手/身关系。手属于身体。 -
但是,我的同事说,允许用户直接调用成员对象的方法(在这种情况下为body->left_hand->func1()
)是一个糟糕的设计。
一个建议是使用getter函数,例如getLeftHand()
,它返回Hand * const
而不是只读公共变量left_hand。
另一种方法是为每个Hand函数创建包装函数,如
class Body
{
Body();
~Body();
leftHandfunc1();
rightHandfunc1();
leftHandfunc2();
rightHandfunc2();
...
leftHandfunc20();
rightHandfunc20();
private:
Hand * _left_hand;
Hand * _right_hand;
};
和
Body::leftHandfunc1()
{
_left_hand->func1();
}
但是,正如您所看到的,Hand的20个方法等于Body中的40个包装函数。此列表预计会增长。我应该采用这种方法吗?
还有更好的选择吗?
答案 0 :(得分:1)
我会为Hand
创建一个公开可用功能的界面(仅限读取权限):
struct IHand
{
public:
virtual void func1() const = 0;
virtual void func2() const = 0;
...
virtual void func20() const = 0;
virtual ~IHand() {}
};
class Hand : public IHand
{
public:
void func1() const;
void func2() const;
...
void func20() const;
private:
Hand();
~Hand();
Hand(const Hand& that);
void operator=(Hand const&);
friend class Body;
};
在Body
课程中,您可以安全地分发const
和_left_hand
的{{1}}参考获取者,如下所示:
_right_hand
客户端可以访问界面,如:
class Body
{
public:
Body();
~Body();
const IHand& left_hand() const { return _left_hand; }
const IHand& right_hand() const { return _right_hand; }
private:
Hand _left_hand;
Hand _right_hand;
};
此设计将匹配您的所有约束:
- 用户无法创建/删除Hand对象。
- 用户无法创建属于Body的Hand对象的副本。
- 用户无法修改Body对象的左手和右手指针。
醇>
我不确定你的最后一点, modify 是什么意思。所以我在界面中创建了所有Body body;
body.left_hand().func1();
body.right_hand().func20();
作为预防措施。