• C++中const限定符的应用


    const限定符用于限定变量或对象的值。const对象一旦创建其值不能再改变。在C++中,const与引用和指针相结合,有多种用法。下面将结合<C++ Primer>第五版的内容做一个较详细的介绍。

    1.const对象初始化

    const对象必须初始化,初始化可以是任意复杂的表达式,如:

        const int i=get_size();

        const int j=42;

    2.如何在文件间共享const对象

    当以编译时初始化的方式定义一个const对象时,编译器将在编译过程中把用到该变量的地方都替换成对应的值。替换的前提是编译器知道变量的初始值。为了避免对同一变量的重复定义,默认情况下,const对象被设定为仅在文件内有效。值得注意的是,当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。

    文件间共享const变量,即希望编译器不会为每个文件分别生成独立的变量。解决的办法是,对于const变量不管是声明还是定义都添加extern关键词,这样只需定义一次就可以,如: 

        //  file_1.cc中定义并初始化了一个常量,该常量能被其他文件访问     

        extern const int bufSize=fcn();

        // file_1.h头文件中对bufSize进行声明

        extern const int bufSize;

    3.const的引用

    对const的引用通常也被简称为“常量引用”(reference to const)。不同于普通引用,对常量的引用自身也是const类型。如:

         const int ci=1024;

         const int &r1=ci;                     //注意这里的引用是常量,去掉const错误

    常量引用仅对引用可参与的操作作出限定,对于引用的对象本身是不是一个常量未做先限定。如:

         int i=42;

         int &r1=i;                               //引用r1绑定对象i

         const int &r2=i;                      //r2也绑定对象i,但是作为常量引用,不允许通过r2修改i的值

    4.指针和const

    4.1指向常量的指针

    与引用类似,想要存放常量对象的地址,只能使用指向常量的指针(pointer to const)。如:

        const double pi=3.14;

        const double *cptr=&pi;

    和常量引用一样,指向常量的指针也没有规定其所指的对象必须是一个常量,即对const的引用和指针都必须是const类型的,但const类型的指针和引用也可以针对非常量的对象。如:

        double dval=3.14;                    //dval是一个双精度浮点数,非常量

        cptr=&dval;                             //指向常量的指针cptr也可以指向dval

    4.2常量指针

    指针本身也是对象,可以把指针本身定义为常量,称为常量指针(const pointer)。常量指针必须初始化,一旦初始化后其值(存放在指针中的地址)不再变化。把*放在const关键词之前用以说明指针是一个常量。如:

         int errNumb=0;

         int *const curErr=&errNumb;    //curErr为常量指针,将一直指向非常量errNumb, 可以通过curErr修改errNumb的值.

         const  double pi=3.14159;

         const double *const pip=&pi;    //pip是一个指向常量对象的常量指针

    对于较复杂的定义,可采取从右向左阅读的有效方法。如pip,离pip最近的是const说明pip为常量,加上*说明pip为常量指针,double说明pip指向double类型对象,const说明pip指向的是常量。

    4.3顶层const和底层const

    狭义的讲,顶层const(top-level const)表示指针本身是个常量,相对的底层const(low-level const)表示指针所指的对象是一个常量。

    广义来讲,顶层const可以表示任意的对象是常量,且对任何数据类型都适用。底层const则与指针和引用等复合类型的基本类型部分有关。比较特殊的是,指针类型既可以是顶层const,也可以是底层const。来看几个例子:

          int i=0;

          int *const p1=&i;                   //p1为常量指针,本身是一个常量,为顶层const

          const int ci=42;                     //ci为常量,是顶层const

          const *p2=&ci;                       //p2为指向常量的指针,其本身的值可以变,为底层const

          const int *const p3=p2;         //靠右的为顶层const,靠左的是底层const,p3既是顶层const也是底层const

          const int &r=ci;                      //引用本身不是对象,用于申明引用的const都是底层const

    在执行拷贝操作时,常量是底层const还是顶层const区别明显,我想这也是将二者进行明显区分的意义所在。顶层const不受拷贝影响:

          i =ci;                                     //拷贝ci的值,ci是一个顶层const,对此操作无影响

          p2=p3;                                 //p2和p3指向的对象类型相同,p3顶层const的部分不影响

    另一方面,底层const受拷贝限制明显。当执行对象的拷贝操作时,考拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换。一般来说,非常量可以转化为常量。

          p2=p3;                                //两者都具有底层const的属性

          p2=&i;                                 //i为普通int变量,int*能转换为const int*

          const int &r2=i;                    //引用为底层const,可以绑定到普通int上

    5.总结

    const作为单纯的常量本身并不复杂,但是与引用和指针相结合以后则较为复杂,需要厘清其中的关系,才能做到灵活应用。

    参考文献

    Stanley B.Lippman,Josee Lajoie,Barbara E.Moo.C++ Primer(5th edition)

  • 相关阅读:
    基本背包问题
    linux 共享内存实现
    Linux内存管理原理
    从inet_pton()看大小端字节序
    linux线程的实现
    简述memcached中的一致哈希
    c语言实现面向对象OOC
    论记忆力
    关于编程内存泄漏
    一道常考fork题挖掘
  • 原文地址:https://www.cnblogs.com/sherylwang/p/3901693.html
Copyright © 2020-2023  润新知