• 【03】尽可能使用const


    1、为什么搞出const关键字?

      const指定一个语义约束,指定一个对象不可修改。如果一个对象不可修改,就应该说出来。

    2、const与指针

      const可以修饰指向之物,也可以修改指针本身。STL中的迭代器是对指针的封装,因此,迭代器也有两个概念:指向常量对象的迭代器和常量迭代器。

      vector<int>::const_iterator; //指向常量的迭代器

      const vector<int>::iterator; // 常量迭代器

    3、const可以与方法产生关联,可以用在方法前,方法中(形参表中),方法后。首先考虑,用在方法前,表示返回值是常量。为什么要返回const对象呢?

      我们知道,方法返回值是一个临时对象,只有类型,没有名称,这个临时对象是方法内局部对象的副本。如果返回不是一个常量,客户端就能实现下面的暴行:

      Rational a,b,c; 

      (a*b)=c; //对方法返回值进行赋值。

      对于内置类型,这样的赋值行为是错误的。对于自定义类型,也应该报错。有一个准则要遵守:自定义类型应该和内置类型在行为上保持一致,除非有特殊情况。因此,为了避免客户端对方法返回值进行赋值,请返回一个const对象。

    4、const在方法中,也就是出现在形参表中,这种情况很好理解,表示形参不可修改。需要注意的是:形参表不同,可以构成过载。如果形参表相同,只是常量性不同,能否构成过载?能不能构成过载的关键是:编译器能不能根据实参确定调用哪个方法,也就是过载方法的匹配程度不一样。

      如果形参是引用或者指针,可以构成过载,这种情况下,形参是实参的别名,根据实参的常量性,可以确定调用哪个方法。

      如果形参不是引用或者指针,不能构成过载,这种情况下,形参是实参的副本,与实参没有了关系,他们和实参的匹配程度是一样的。

    5、const在方法后,表示常量方法,应该尽量使用常量方法。有两个好处:a、接口容易理解,明确表示不会修改对象内容;b、使得const对象可以调用。

      考虑,我们知道non-const对象可以调用const成员方法,但是,const对象不能调用non-const成员方法,因为non-const成员方法可能会修改对象。为了让const对象调用non-const成员方法,有两种办法:一是使用const_cast<T&>或者const_cast<T*>去除对象的常量性,二是如果不修改对象,使用const成员方法,显然第二种办法更好。

    6、根据成员方法的常量性,可以过载。为什么?我们知道成员方法有个隐式的常量this指针(不能指向其他对象),const成员方法限制了this指针指向const。因此,编译器可以根据方法拥有者的常量性,决定哪个方法更匹配。

    7、如果返回对象的内部数据,const成员方法应该返回const引用,防止外部修改,non-const成员方法应该返回non-const引用。这里特别注意一点,内置类型的临时对象是不可修改的(exception的临时对象是可以修改的),也就是说,内置类型的临时对象不能赋值给non-const引用,考虑一下为什么?

      方法返回对象的内部数据,返回值不是引用,而是内部数据的副本。第一个理由上面讲了,防止客户端对返回值赋值,第二个理由是,如果返回值不是const,就可以赋值给non-const引用,程序员用这个引用期望修改对象内部数据,是办不到的,这个时候修改的是临时对象,这往往不是程序员所期望的。

    8、返回对象的内部数据,const成员方法为什么返回const引用?

      我们知道,const成员方法的语义是说,不修改对象。但是由于暴露了内部数据,自己承诺不修改,但是由于自己的原因,暴露了内部数据,导致外部可以间接修改对象(我不杀伯仁,奈何伯仁因我而死)。为了避免这种情况,返回const引用,限制外部也不能修改。

    9、在有些极端情况下,const成员方法也要修改对象的一部分内部数据,但是我又不想把它设计成non-const成员方法,因为non-const成员方法可以修改对象内的任意数据。这种情况下,可以使用mutable修饰字段,明确表示这些字段可以在const成员方法中修改。

    10、对于过载的const成员方法和non-const成员方法,做的事情一样,只不过一个返回const引用,一个返回non-const引用,如何避免代码重复呢?

      就是让一个方法调用另一个方法,让non-const成员方法调用const成员方法,这里要做两个强制转化,首先使用static_static<const T *>,把常量this指针转化为指向常量对象的常量this指针,然后使用const_cast<T&>,去除返回值的常量性。

      注意:不能反向调用,也就是说,不能使用const成员方法调用non-const成员方法,因为后者可能修改对象内容。

  • 相关阅读:
    IntelliJ IDEA 14.03 java 中文文本处理中的编码格式设置
    应聘感悟
    STL string分析
    CUDA SDK VolumeRender 分析 (1)
    BSP
    CUDA SDK VolumeRender 分析 (3)
    CUDA SDK VolumeRender 分析 (2)
    Windows软件发布时遇到的一些问题
    Ten Commandments of Egoless Programming (转载)
    复习下光照知识
  • 原文地址:https://www.cnblogs.com/nzbbody/p/3518019.html
Copyright © 2020-2023  润新知