const in cpp

const限定符

c++中默认const对象仅在当前文件内有效。这是因为编译器在编译过程中把用到该const变量的地方全都替换成对应的值,当然为了完成上述替换动作,const对象就必须被初始化。

为了能够在别的源文件中也能使用某个const变量,可以在声明和定义的地方都加上extern修饰。可以理解为用extern来抵消const所带来的链接属性的影响。

const通常需要注意的两点:

  • const引用
  • 顶层const以及底层const

const引用

对于const引用,有一点要注意的是在初始化常量引用的时候,允许用任意表达式作为初始值,前提是只要该表达式的结果能够转化成引用的类型即可。如下都是可以的:

    int i = 42;
    const int &r1 = i;
    const int &r2 = 42;
    int &r3 = 42;//error 非常量的引用的初值必须为左值

其实这是很容易理解的,因为const引用,即相当于我们告诉编译器,不能通过该引用去修改所引用对象的值。即考虑如下代码:

    double i = 42.3;
    const int &r1 = i;

为了确保上述代码中r1绑定到一个int类型的变量上,编译器实际上会把上述代码变成:

    double i = 42.3;
    const int temp = i;
    const int &r1 = temp;

即r1实际上是绑定到了这个临时对象上。之所以能够这么做,是因为我们不会通过常量引用去修改该对象。

顶层const与底层const

顶层const即const修饰的对象本身是const,这对于任何数据类型都适用。但是底层const则是与指针或者引用等复合类型的基本类型部分有关。
如下:

    int i = 0;
    int *const p1 = &i;// top-level const, 顶层const,不能修改p1的值
    const int * p2 = &i;// low-level const,底层const,不能通过p2修改i的值

    const int &r1 = i;//用于声明引用的const都是底层const

两种所带来的区别是对于在执行拷贝操作的时候,顶层const的影响可以忽略,但是拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能够转换,一般非const能够转换为const,如下:

    int i = 0;
    const int * const p3 = &i;//ok
    const int j = 0;
    int *const p4 = &j;//error 不能用const int *的对象初始化int*的对象
    const int * p5 = &i;//ok, 非const能够转换为const
发布了24 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ck1n9/article/details/81437104
cpp