Item28: Avoid returning “handles” to object internals.
避免返回 handles
(包括 references
、指针、迭代器)指向对象内部。
破坏封装性
const
函数不再是 const
, 修改了私有成员变量。
1 | class Point { |
虽然这样的设计可通过编译,但却是错误的。upperLeft
和 lowerRight
被声明为 const
成员函数,但是可以更改内部数据。
1 | Point coord1(0, 0); |
- 成员变量的封装性最多只等于”返回其
reference
“ 的函数的访问级别。 - 如果
const
成员函数传出一个reference
,后者所指数据与对象自身有关联,而它又被存储于对象之外,那么这个函数的调用者可以修改那笔数据。(bitwise constness
原因)
悬空问题
虽然我们可以修改函数,达到不能修改私有成员变量。
1 | const Point& upperLeft() const { return pData->ulhc; } |
但也不能解决悬空问题。如下:
1 | class GUIObject { ... }; |
现在,客户有可能这么使用这个函数:
1 | GUIObject* pgo; // 让pgo指向某个GUIObject |
pUpperLeft
被悬空了,boundingBox(*pgo)
返回的是一个临时变量,在语句执行结束后就会销毁,导致 pUpperLeft
指针失效。