Effective C++ Item 28 避免返回对象内部数据的引用或指针
本文为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 避免返回对象内部数据的引用或指针的更多相关文章
- Effective c++ Item 28 不要返回对象内部数据(internals)的句柄(handles)
假设你正在操作一个Rectangle类.每个矩形可以通过左上角的点和右下角的点来表示.为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放 ...
- 读书笔记 effective c++ Item 28 不要返回指向对象内部数据(internals)的句柄(handles)
假设你正在操作一个Rectangle类.每个矩形可以通过左上角的点和右下角的点来表示.为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放 ...
- 条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
先看第一种情况:返回一个局部对象的引用.它的问题在于,局部对象 ----- 顾名思义 ---- 仅仅是局部的.也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的.所谓生命空间,是指它们所在的 ...
- Effective JavaScript Item 55 接受配置对象作为函数參数
接受配置对象作为函数參数 尽管保持函数接受的參数的顺序非常重要,可是当函数可以接受的參数达到一定数量时.也会让用户非常头疼: var alert = new Alert(100, 75, 300, 2 ...
- 读书笔记 effective c++ Item 3 在任何可能的时候使用 const
Const可以修饰什么? Const 关键字是万能的,在类外部,你可以用它修饰全局的或者命名空间范围内的常量,也可以用它来修饰文件,函数和块作用域的静态常量.在类内部,你可以使用它来声明静态或者非 ...
- Effective C++:条款28:避免返回 handles 指向对象内部成员
(一) 有时候为了让一个对象尽量小,能够把数据放在另外一个辅助的struct中,然后再让一个类去指向它.看以下的代码: class Point { public: Point(int x, int y ...
- [Effective C++ --028]避免返回handles指向对象内部成分
假设程序涉及矩形.每个矩形由其左上角和右下角表示.为了让Rectangle对象尽可能小,可能把定义矩形的点放在一个辅助的struct内再让Rectangle去指它: class Point { // ...
- Effective C++ Item 46 当需要投你非成员函数定义模板
本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当我们编写一个 class template, 而它所提供之"与此 temp ...
- c++逆向分析----返回对象
对象不使用默认析构函数 class Test { public: char cNum1; int iNum2; int* pInt; }; Test _ReturnObject() { Test st ...
随机推荐
- 【BZOJ2693】jzptab & 【BZOJ2154】Crash的数字表格
题目 弱化版题目的传送门([BZOJ2154]Crash的数字表格) 加强版题目的传送门([BZOJ2693]jzptab) 思路&解法 题目是要求: \(\sum\limits_{i = 1 ...
- IPv6系列-初学者的10个常见困扰
本文是<IPv6系列>文章的第二篇<常见困扰>,紧接<入门指南>,用于解答IPv6的10个常见困扰. 小慢哥的原创文章,欢迎转载 目录 ▪ 本文缘由 ▪ 困扰1. ...
- Spring Boot (1) 构建第一个Spring Boot工程
Spring boot简介 spring boot是spring官方推出的一个全新框架,其设计目的是用来简化新spring应用的初始搭建以及开发过程. Spring boot特点 1.化繁为简,简化配 ...
- netty 引用计数对象(reference counted objects)
[Netty官方文档翻译]引用计数对象(reference counted objects) http://damacheng009.iteye.com/blog/2013657
- 安卓学习之学生签到APP(一)
一.学生定位签到页面 具体实现步骤: 1.1 高德地图申请key 1.创建新应用 进入高德地图api控制台,创建一个新应用.如果您之前已经创建过应用,可直接跳过这个步骤. 2.添加新Key 在创建的应 ...
- matlab中 注意事项--字符串
Matlab中的字符串操作 原文链接:http://hi.baidu.com/dreamflyman/item/bd6d8224430003c9a5275a9f (1).字符串是以ASCII码形式存储 ...
- MFC 添加文件路径 遍历文件
.添加MFC选择文件路径,使用MessageBox显示信息. void CMyCalLawsDlg::OnBnClickedAddfolder() { wchar_t* p; wchar_t szPa ...
- 在 ef 中执行 DbContext.Table.AddRange(Enitites).ToList() 会发生什么
在 ef 中执行 DbContext.Table.AddRange(Enitites).ToList() 会发生什么 昨天和朋友摸鱼,无意之间聊到了执行 DbContext.Table.AddRang ...
- Android中DatePicker与TimePicker用法讲解(包括DatePickerDialog与TimePickerDialog)
实现效果:将DatePicker和TimePicker修改的日期和时间实时显示在程序标题栏上. 1.通过DatePicker和TimePicker来实现 布局为main.xml <?xml ve ...
- Redis好在哪?
Redis免费入门教程:阿里云大学—开发者课堂 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. Redis ...