Effective C++ 条款28
避免返回handles指向对象内部成分
本节作者讲述的知识核心是对于一个类来说,应该避免类返回自己内部的私有数据。
例如以下:
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{
……
private:
std::tr1::shared<RectData> pData;
};
class Rectangle{
……
public:
Point& upperLeft()const{return pData->ulhc;}//应该尽量避免
Point& lowerRight()const{return pData->lrhc;}//应该尽量避免
};
为什么要避免这样的调用呢?非常easy,为了避免非法改动被调用的私有数据
例如以下:
Point coord1(0,0);
Point coord1(100,100);
const Rectangle rec(coord1,coord2);
rec.upperLeft().setX(50);//被非法改动,并且此类行为不易被察觉
有什么解决的方法?
解决的方法例如以下:
class Rectangle{
……
public:
const Point& upperLeft()const{return pData->ulhc;}
const Point& lowerRight()const{return pData->lrhc;}
};
上述採用的方式是声明函数返回const对象。
可是,这样的方式也不能根治问题,例如以下:
class GUIObject{……}。
const Rectangle boundingBox(const GUIObject& obj);
GUIObject* pgo;
const Point* pUpperLeft=&(boundingBox(*pgo).upperLeft());
调用boundingBox获得一个新的、暂时的Rectangle对象,暂时对象没有名字。暂且成为temp,随后upperLeft作用于temp身上,返回一个reference指向temp的一个内部成分。于是,pUpperLeft指向这个Point对象。问题出在temp是一个暂时对象。当这个语句结束后,暂时对象便会析构。这时pUpperLeft指向一个不再存在的对象。pUpperLeft变成空悬、虚吊(dangling)。
总结:
避免返回handles(reference、指针、迭代器)指向对象内部。遵守这个条款能够添加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handles)的风险降到最低。
Effective C++ 条款28的更多相关文章
- Effective C++ -----条款28:避免返回handles指向对象内部成分
避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...
- [More Effective C++]条款22有关返回值优化的验证结果
(这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...
- More Effective C++ 条款0,1
More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...
- Effective C++:条款28:避免返回 handles 指向对象内部成员
(一) 有时候为了让一个对象尽量小,能够把数据放在另外一个辅助的struct中,然后再让一个类去指向它.看以下的代码: class Point { public: Point(int x, int y ...
- Effective C++ 条款08:别让异常逃离析构函数
1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...
- Effective C++ -----条款21:必须返回对象时,别妄想返回其reference
绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...
- Effective C++ -----条款19:设计class犹如设计type
Class的设计就是type的设计.在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有讨论主题. 新type的对象应该如何被创建和销毁? 对象的初始化和对象的赋值该有什么样的区别? 新typ ...
- Effective C++ -----条款18:让接口容易被正确使用,不易被误用
好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...
- Effective C++:条款27——条款
条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!
随机推荐
- thinkphp5 left join
thinkphp5 left join 一.总结 1.作用:left join就是即使不匹配也返回左表中的数据 2.join使用通式:object join ( mixed join [, mixed ...
- 用Fiddle跟踪调试移动表单
简介:Fiddle,调试,移动表单 http://jingyan.baidu.com/article/925f8cb81e3a52c0dde05616.html
- js全选反选按钮实现
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 有趣的Ruby-学习笔记4
Ruby块 块.在我看来就是插入一段可变的函数 block_name{ statement1 statement2 .......... } 看起来不知道是什么,只是别急,继续往下看. 块函数通过yi ...
- Xcode6:No architectures to compile for(ONLY_ACTIVE_ARCH=YES...)
1.问题描写叙述 Xcode6真机測试旧project,不能执行,报错例如以下: 2.解决方式 问题非常明显,当前的执行模式设置了ONLY_ACTIVE_ARCH为Yes,当时的project的Val ...
- Elasticsearch和MongoDB
Elasticsearch和MongoDB分片及高可用对比 本文旨在对比Elasticsearch和MongoDB高可用和分片的实现机制. Elasticsearch ES天生就是分布式的,那她又是如 ...
- 对DataTable进行过滤筛选的一些方法Select,dataview
当你从数据库里取出一些数据,然后要对数据进行整合,你很容易就会想到: DataTable dt = new DataTable();//假设dt是由"SELECT C1,C2,C3 FROM ...
- JS contcat() 连接数组 函数
语法: arrayObject.concat(arrayX,arrayX,......,arrayX) 1.把元素添加到数组中 arr.concat(a,b,c);2.把数组连起来 arr.conca ...
- amazeui学习笔记--css(常用组件13)--进度条Progress
amazeui学习笔记--css(常用组件13)--进度条Progress 一.总结 1.进度条基本使用:进度条组件,.am-progress 为容器,.am-progress-bar 为进度显示信息 ...
- UVA 11796 - Dog Distance 向量的应用
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...