首先,让我重申一下:最大的问题不是生命周期,而是封装问题。
封装不仅意味着没有人可以在您不知道的情况下修改内部,封装意味着没有人知道您的类中的事物是如何实现的,因此只要您保持接口相同,您就可以随意更改类内部。
现在,你返回的引用是否const无关紧要:你不小心暴露了Mother你的类中有一个对象的事实,Family现在你无法摆脱它(即使你有更好的表示),因为你所有的客户可能会依赖它,并且必须更改他们的代码......
最简单的解决方案是按值返回:
class Family {
public:
Mother mother() { return _mother; }
void mother(Mother m) { _mother = m; }
private:
Mother _mother;
};
因为在下一次迭代中,我可以在_mother不破坏界面的情况下删除:
class Family {
public:
Mother mother() { return Mother(_motherName, _motherBirthDate); }
void mother(Mother m) {
_motherName = m.name();
_motherBirthDate = m.birthDate();
}
private:
Name _motherName;
BirthDate _motherBirthDate;
};
看看我是如何在不改变界面的情况下完全改造内部结构的?十分简单。
注意:显然这种转换只是为了效果......
显然,这种封装是以牺牲一些性能为代价的,这里有一个张力,每次编写 getter 时,是否应该首选封装还是性能是你的判断。