Effective C++读书笔记之避免返回handles指向对象内部成分

 我们举个例子来看这个条款面临的问题
 设计一个表示矩形的类,为了让这个类尽量的小,可以不把表示矩形的点放在这个类中,而是放在一个struct中,在类中指向它。
 class Point {          //表示点的类
 public:
  Point(int x, int y);
  .....
  void setX(int newVal);
  void setY(INT newVal);
 };
 struct RectData {     //这些点数据用来表现一个矩形
  Point ulhc;   //upper left hand corner
  Point lrhc;   //lower right hand corner
 };
 class Rectangle {
 public:
  Point& upperLeft()  const {return pData->ulhc; }
  Point& lowerRight() const {return pData->lrhc; }
  private:
  std::trl::shared_ptr<RectData> pData;   //指向了结构体
 };
 上面这样的设计的问题:在类Rectangle中我们提供upperLeft和lowerRight函数只是为了返回矩形的范围的,所以我们声明为const。可是由于它返回reference指向private内部数据,调用者于是可通过这些references更改内部数据。例如:
 Point coord1(0.0);
 Point coord1(100.100);
 const Rectangle rec(coord1, coord2);  //rec是不可改变的矩形
 rec.upperLeft().setX(50);    //通过返回的reference修改了矩形,这是和我们的设计初衷不符的
 造成上面问题的根本原因是:类的成员函数返回了指向类的私有成员的reference。如果它们返回的是指针或迭代器,情况是一样的。Reference,指针和迭代器都是所谓的handles。因些应该避免类的成员函数返回这样的handles。
 解决方法:
 声明其返回一个静态的reference。例:
 class Rectangle {
 public:
  const Point& upperLeft()  const {return pData->ulhc; }
  const Point& lowerRight() const {return pData->lrhc; }
  private:
  std::trl::shared_ptr<RectData> pData;   //指向了结构体
 };
 这样的reference只允许你读取,不可以修改。
 
 上面的问题结决了,可是upperLeft和lowerRight还是返回了指向内部对象的handles。这还会出现一个问题就是dangling handles。就是说这种handles所指向东西不复存在,它通常发生在函数返回值时。
 例如:某个函数返回GUI对象的外框(bounding box),这个外框采用矩形形式:
 class GUIObject {....};
 const Rectangle boundingBox(const GUIObject& obj);//以by value返回一个矩形
 客户可以使用这个函数,如:
 GUIObject* pgo;    //以pgo指向某个GUIObject
 ....
 const Point* pUpperLeft = &(boundingBox(*pgo).UpperLeft()); //取得一个指针指向外框左上点
 问题出在boundingBox(*pgo)获得的是一个临时的Rectangle对象,这个语句之后这个临时的对象就被销毁了,可是UpperLeft返回了一个Reference指向一个Points。这导致了返回的Reference指向了一个空的对象。所以要避免类的成员函数返回这样的handles
 
 总结:
 避免返回handles(包括references,指针,迭代器)指向对象内部。遵守这个条款增加封装性,帮助const成员函数的行为像个const,并将发生”虚吊号码牌“dangling handles 的可能性降至最低

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值