zoukankan      html  css  js  c++  java
  • 读书笔记_Effective_C++_条款二十八:避免返回handlers指向对象内部成分

    举个例子:

     1 class Student
     2 {
     3 private:
     4     int ID;
     5     string name;
     6 public:
     7     string& GetName()
     8     {
     9         return name;
    10     }
    11 };

    这是一个学生的类,类里面有两个成员变量,一个是学生ID,用整数表示,另一个是姓名,用string表示。有一个公有的方法GetName(),获得学生的名字,根据条款20所说的,使用引用可以防止资源不必要地拷贝,那么在返回值这边就用string&。但现在问题来了,这个函数只是想返回学生的姓名,并不想用户对之进行修改,但返回引用却提供了这样的一个接口,如:

    int main()
    {
        Student s;
        s.GetName() = "Jerry";
        cout << s.GetName() << endl;
    }

    就可以把名字进行修改。

    你也许想到了,如果在前面加上const,像这样:

    1 const string& GetName()
    2 {
    3     return name;
    4 }

    就可以阻止s.GetName() = “Jerry”这样的代码了。

    但这样写还是存在问题,就是如果返回的引用生命周期比对象本身要长时,引用就会悬空,它会指向一个不存在的string。下面看一下“返回的引用生命周期比对象本身要长”的情况,这种情况还是很容易举出例子的,比如:

    1 const string& fun()
    2 {
    3     return Student().GetName();
    4 }
    5 
    6 int main()
    7 {
    8     string name = fun(); //name指向一个不存的对象的成员变量
    9 }

    这时候即使name读取不报错,也是一个巨大的隐患,因为它已经是虚吊(dangling)的了。

    这就是为什么函数如果“返回一个handle代表对象内部成分”总是危险的原因,不在于返回值是不是const,而是在于如果handle(指针或引用)传出去了,就会暴露在“handle比其所指对象更长寿”的风险下。

    但有些情况还是需要返回handle的,比如string或者vector里面的operator[],就是返回的引用,因为需要对这里面的元素进行操作。

    好了,总结一下:

    避免返回handles(包括reference、指针、迭代器)指向对象内部,遵守这个条款可增加封装性,并将发生dangling handles的可能性降至最低。如果有必要必须要返回handles,在编写代码时就一定要注意对象和传出handle的生命周期。

  • 相关阅读:
    Ubuntu 12.04.2 发布
    HornetQ 2.3.0.CR1 发布,异步消息系统
    Django 1.5.1 发布,修复内存泄漏问题
    Subclipse 1.8.20 发布,Eclipse 的 SVN 插件
    Cython 0.18 发布,Python 的 C 语言扩展
    GlusterFS 正式推出,支持 OpenStack
    瀑布流布局图片URL以blob格式展示
    Windows 开发环境使用 mkcert 为本机 localhost 自签 SSL 证书
    Windows手动添加服务 sc create
    FileZilla Server 新版配置教程,550错误解决
  • 原文地址:https://www.cnblogs.com/jerry19880126/p/3162760.html
Copyright © 2011-2022 走看看