本文为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. [转]利用 NPOI 變更字體尺寸及樣式

    本文转自:http://blog.cscworm.net/?p=1650 利用 NPOI 變更字體尺寸及樣式: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ...

  2. BZOJ 3727 DP?推式子..

    思路: 设$sum[i]表示i的子树中a[i]的和$ $b[1]=\Sigma a[i]*dis[i] = \Sigma _{i=2} ^n sum[i]$ $b[x]-b[fa[x]]=sum[1] ...

  3. B - Taxi(贪心)

    Problem description After the lessons n groups of schoolchildren went outside and decided to visit P ...

  4. C - Stones on the Table

    Problem description There are n stones on the table in a row, each of them can be red, green or blue ...

  5. html与css命名规范小结

    一.命名规则说明 所有的命名最好都用小写 使用英文命名 给每一个表格和表单加上一个唯一的.结构标记id 给每个图片加上alt标签,优点在于图片发生错误时,alt可以体现给用户 二.相对网页外层重要部分 ...

  6. (转)Vue 爬坑之路(二)—— 组件之间的数据传递

    Vue 的组件作用域都是孤立的,不允许在子组件的模板内直接引用父组件的数据.必须使用特定的方法才能实现组件之间的数据传递. 首先用 vue-cli 创建一个项目,其中 App.vue 是父组件,com ...

  7. (转)淘淘商城系列——Solr集群搭建

    http://blog.csdn.net/yerenyuan_pku/article/details/72957201 我们之前做的搜索使用的是Solr的单机版来实现的,正是由于我们现在商品数据量不多 ...

  8. 说说web缓存-强缓存、协商缓存

    网上关于WEB缓存的文章很多,今天汇总一下. 为什么要用缓存 一般针对静态资源如CSS,JS,图片等使用缓存,原因如下: 请求更快:通过将内容缓存在本地浏览器或距离最近的缓存服务器(如CDN),在不影 ...

  9. Python统计字符串中出现次数最多的人名

    人名最多数统计题目摘自https://python123.io 描述编程模板中给出了一个字符串,其中包含了含有重复的人名,请直接输出出现最多的人名.‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬ ...

  10. Deepin & ROMS 安装详细流程

    按照这个过程,完美安装,当然并不能排除会出现其他的问题.如果遇到了,那就老老实实上网搜吧.