避免返回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的更多相关文章

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

    避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...

  2. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  3. More Effective C++ 条款0,1

    More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...

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

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

  5. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  6. Effective C++ -----条款21:必须返回对象时,别妄想返回其reference

    绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...

  7. Effective C++ -----条款19:设计class犹如设计type

    Class的设计就是type的设计.在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有讨论主题. 新type的对象应该如何被创建和销毁? 对象的初始化和对象的赋值该有什么样的区别? 新typ ...

  8. Effective C++ -----条款18:让接口容易被正确使用,不易被误用

    好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...

  9. Effective C++:条款27——条款

    条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!

随机推荐

  1. tee---读取标准输入,将内容输出成文件

  2. 关于Blocking IO,non-Blokcing IO,async IO的区别和理解

    来源:http://shmilyaw-hotmail-com.iteye.com/blog/1896683 概括来说,一个IO操作可以分为两个部分:发出请求.结果完成.如果从发出请求到结果返回,一直B ...

  3. Cocos2d-x 之大牛看法

    (未完毕) cocos2d-x并非一个适合网游client(mmo)的游戏引擎.越是大型游戏,这个小引擎就越无法驾驭(尽管它很受欢迎). 之前我在原来的公司使用的是自主研发的C3引擎,已经对外开放(尚 ...

  4. Linux - 用 Konstruct 安装 KDE 3.x

    make-kde3.x Linux - 用 Konstruct 安装 KDE 3.x 找个截图工具 khtml2png (http://khtml2png.sourceforge.net/), 现在都 ...

  5. intent- 启动其他应用

    今天需要在图库中实现对相机的调用,代码如下 Intent intent = new Intent(Intent.ACTION_VIEW); ComponentName componetName = n ...

  6. 26.event跨进程通信

    以id创建事件 ] = "myevent"; HANDLE event = CreateEventA(NULL, FALSE, FALSE, name); 设置事件 SetEven ...

  7. Navigator对象关于语言的属性

    [摘要]在做国际化WEB项目的时候,遇到了一个根据用户浏览器所使用的自然语言切换默认语言版本的问题.于是,整理了这篇文章. 首先,W3Cschool关于Navigator的各个属性值说的很明确了,这里 ...

  8. http压测工具wrk

    安装 wrk支持大多数类UNIX系统,不支持windows.需要操作系统支持LuaJIT和OpenSSL,不过不用担心,大多数类Unix系统都支持.安装wrk非常简单,只要从github上下载wrk源 ...

  9. 使用C#对XML进行增删改查操作

    xml文件格式 <?xml version="1.0" encoding="utf-8"?> <messageList> <mes ...

  10. 【2017"百度之星"程序设计大赛 - 初赛(A)】数据分割

    [链接]http://acm.hdu.edu.cn/showproblem.php?pid=6109 [题意] 在这里写题意 [题解] 要处理的关系越多,肯定就越容易错. ->单调性. 根据这个 ...