本文为senlie原创。转载请保留此地址:http://blog.csdn.net/zhengsenlie

Item 31



经验:避免返回handles(包含 references、指针、迭代器)指向对象内部。遵守这个条款可添加封装性。

帮助 const 成员函数的行为像个 const。并将发生“虚吊号码牌”(dangling handles)的可能性降至最低。

演示样例:

class Point{
public:
Point(int x, int y);
//...
void setX(int newVal);
void setY(int newVal);
//...
};
struct RectData{
Point ulhc;
Point urhc;
}
class Rectangle{
public:
//...
Point &upperLeft() const {return pData->ulhc;} // bitwise constness --> const 函数仅仅保证成员变量的值不变。不保证成员变量指针所指的值不变
Point &lowerRight() const {return pData->lrhc;}
//...
private:
std::tr1::shared_ptr<RectData> pData; // pimpl实现 --> Item 31
}; Point coord1(0,0);
Point coord2(100,100);
const Rectangle rec(coord1, coord2);
rec.upperLeft().setX(50); // rec 是个const 矩形。从(0,0)到(100,100)。但如今 rec 却变成 从(50,0) 到(100, 100)

解析:返回一个“代表对象内部数据”的handle,随之而来的便是“减少对象封装性”的风险。

不该令成员函数返回一个指针指向“訪问级别较低”的成员函数或成员变量,那样,后者的实际訪问级别就会提高如同前者。

纠正1:在返回类型加上 const

class Rectangle{
public:
//...
const Point &upperLeft() const {return pData->ulhc;}
const Point &lowerRight() const {return pData->lrhc;}
//...
};

解析:加了 const 后,尽管客户不能必然它们,但它还是可能导致 dangling handles:这样的handles所指东西不复存在。

演示样例:

class GUIObject (...);
const Rectangle boundingBox (const GUIObject &obj); //1.为什么以 by value 方式返回? 自己定义类型不是reference 更好吗? --> 由于 Rectangle 是 GUIObject的内部对象?
//2.既然以by value返回,为什么还要加const,反正返回的是副本,客户改了也没关系呀?
GUIObject *pgo;
//...
const Point *pUpperLeft = &(boundingBox(*pgo).upperLeft()); //这条语句之后 boundingBox返回的对象被析构。间接导致该对象内的Points析构,终于导致 pUpperLeft指向一个不存在的对象

解析:handle比其所指对象更长寿





例外:operator[]会返回strings和vectors的个别元素,这些operator[]就是返回 reference 指向 “容器内的数据”

Effective C++ Item 28 避免返回对象内部数据的引用或指针的更多相关文章

  1. Effective c++ Item 28 不要返回对象内部数据(internals)的句柄(handles)

    假设你正在操作一个Rectangle类.每个矩形可以通过左上角的点和右下角的点来表示.为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放 ...

  2. 读书笔记 effective c++ Item 28 不要返回指向对象内部数据(internals)的句柄(handles)

    假设你正在操作一个Rectangle类.每个矩形可以通过左上角的点和右下角的点来表示.为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放 ...

  3. 条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用

    先看第一种情况:返回一个局部对象的引用.它的问题在于,局部对象 ----- 顾名思义 ---- 仅仅是局部的.也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的.所谓生命空间,是指它们所在的 ...

  4. Effective JavaScript Item 55 接受配置对象作为函数參数

    接受配置对象作为函数參数 尽管保持函数接受的參数的顺序非常重要,可是当函数可以接受的參数达到一定数量时.也会让用户非常头疼: var alert = new Alert(100, 75, 300, 2 ...

  5. 读书笔记 effective c++ Item 3 在任何可能的时候使用 const

    Const可以修饰什么?   Const 关键字是万能的,在类外部,你可以用它修饰全局的或者命名空间范围内的常量,也可以用它来修饰文件,函数和块作用域的静态常量.在类内部,你可以使用它来声明静态或者非 ...

  6. Effective C++:条款28:避免返回 handles 指向对象内部成员

    (一) 有时候为了让一个对象尽量小,能够把数据放在另外一个辅助的struct中,然后再让一个类去指向它.看以下的代码: class Point { public: Point(int x, int y ...

  7. [Effective C++ --028]避免返回handles指向对象内部成分

    假设程序涉及矩形.每个矩形由其左上角和右下角表示.为了让Rectangle对象尽可能小,可能把定义矩形的点放在一个辅助的struct内再让Rectangle去指它: class Point { // ...

  8. Effective C++ Item 46 当需要投你非成员函数定义模板

    本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当我们编写一个 class template, 而它所提供之"与此 temp ...

  9. c++逆向分析----返回对象

    对象不使用默认析构函数 class Test { public: char cNum1; int iNum2; int* pInt; }; Test _ReturnObject() { Test st ...

随机推荐

  1. bzoj2822[AHOI2012]树屋阶梯(卡特兰数)

    2822: [AHOI2012]树屋阶梯 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 879  Solved: 513[Submit][Status] ...

  2. Wireshark 、HTTPWatch、Fiddler的介绍

    一.Wireshark  <TCP/IP协议监听> Wireshark(前称Ethereal)是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包 ...

  3. Spark2.0.2+Zeppelin0.6.2 环境搭建 初探

    0.抱怨与其他(此部分与标题没有太多联系): 首先一点想说的是版本问题,为什么标题我会写清楚版本号呢!原因就是版本不对真的很会坑人. 就在写这篇博客的同一天,我还写了另一篇,是 Hadoop2.7.3 ...

  4. [SGU 199] Beautiful People

    [SGU 199] Beautiful People The most prestigious sports club in one city has exactly N members. Each ...

  5. mygenerator().next() AttributeError: 'generator' object has no attribute 'next'

    def mygenerator(): print ("start ...") yield 5 mygenerator() print ("mygenerator():&q ...

  6. 证明,为什么HBase在创建表时,列簇是必须要,列可不要?

    若是删除不存在的列修饰符,看下会是什么情况 package zhouls.bigdata.HbaseProject.Test1; import javax.xml.transform.Result; ...

  7. WPF播放器

    最近由于工作需要,需要做一个播放软件,在网上参考了很多例子,园子里有很多代码.其中最多的就是wpf自带的MediaElement控件,或者VLC视频播放器. 先附我自己查询资料的链接: MediaEm ...

  8. Multipart/form-data POST文件上传

    简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form method="post"action=&qu ...

  9. 酷派改变者S1(C105/C105-6/C105-8) 解锁BootLoader 并刷入recovery root

    首先下载好工具链接:https://pan.baidu.com/s/1qZjOCUw 密码:u2dr 备用下载链接:https://pan.baidu.com/s/1pMlmAef 本篇教程教你如何傻 ...

  10. 【Oracle】详解ADDM工具

    一.ADDM简介           在Oracle9i及之前,DBA们已经拥有了很多很好用的性能分析工具,比如,tkprof.sql_trace.statspack.set event 10046& ...