C++实现之——尽量避免返回handles指向对象内部成分

定义下面的类和结构:

 1 class Point
 2 {
 3 public:
 4      Point(int x, int y);
 5      ...
 6      void setX(int newVal);
 7      void setY(int newVal);
 8 };
 9 struct RectData
10 {
11      Point ulhc;
12      Point lrhc;
13 };
14 class Rectangle
15 {
16      ...
17 private:
18      std::tr1::shared_ptr<RectData> pData; 
19 };

那么下面的成员变量是否有不合理的地方:

1 class Rectange
2 {
3 public:
4     Point& upperLeft() { return pData->ulhc; }
5     Point& lowerRight() { return pData->lrhc; }
6 ...
7 };

上面不合理的地方在第4和第5行,const成员变量的本意是只返回数据,但不允许修改对象内部的数据,但是上面的代码由于返回了指向对象内部变量的handle,破坏了封装性,因为用户可以通过这个handle来修改Point的属性。为了解决这个问题,可以令这个handle为const,这样就不可修改,即:

1 const Point& upperLeft() { return pData->ulhc; }
2 const Point& lowerRight() { return pData->lrhc; }

即使如此,返回指向对象内部的handle还可能带来其他的问题,比如返回一个空的handle,例如下面的代码:

1 class GUIObject { ... };
2 const Rectangle boundingBox(const GUIObject& obj);
3 
4 GUIObject* pgo;
5 ...
6 const Point* pUpperLeft = &(boundingBox(*pgo).upperLeft));

第6行Point指向boundingBox(*pgo)获得的一个临时对象的一个内部成员,但是由于boundingBox(*pgo)返回对象在语句6执行结束后就会被析构,从而导致其内部成员变量Point对象也会被析构,因而pUpperLeft将指向一个空的对象,即变成空悬、虚吊即dangling的handle。

 当然,并不是所有的成员函数都不该返回handle,例如operator[],它需要返回指向容器内部数据的handle。

综上,在定义类的过程中,应避免返回handle指向对象内部成分,这样可以增加封装性,使得const成员函数执行起来真正具有const的性质,并避免得到虚吊的handle。

 

以上整理自Effective C++中文版第三版case 28.

 

 

 

 

转载于:https://www.cnblogs.com/sophia-yun/archive/2013/06/03/3115706.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值