zoukankan      html  css  js  c++  java
  • c++中的 const 关键字

    知识回顾:C语言中 const

      const 修饰的变量是 只读的,本质上还是变量;(只读变量:可以通过指针修改只读变量中的值)

      const 修饰的局部变量在栈上分配空间;

      const 修饰的全局变量在只读存储区分配空间;

      const 只在编译期间生效,在运行期间无效

      const 修饰的变量不是真的常量,它只是告诉编译器该变量不能出现在赋值符号的左边;

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     const int c = 10;   // c 是只读变量
     6     int* p = (int*)&c;
     7     
     8     *p = 5;
     9     
    10     printf("c = %d
    ", c);  // c = 5
    11     
    12     return 0;
    13 }
    14 // 编译器 gcc
    c语言中 const


    c++ 中 const

    1. const 常量

      1)const 修饰的变量 是一个真正的常量;

        这是由于c++中使用的符号表机制,当使用一个字面量初始化const变量时,就会将该字面量放入符号表中;在编译过程中,若发现使用该变量,就会将这个变量替换为符号表中值;

      2)在编译过程中,若发生以下情况,则可能会给对应的常量分配存储空间;

        1、当 const 常量为全局时,并且需要在其它文件中使用;(extern

        2、当使用 & 操作符对 const 常量取地址;

           注:c++ 编译器虽然可能为 const 常量分配存储空间,但不会使用其存储空间中的值

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     const int c = 10;   // c 是常量
     6     int* p = (int*)&c;
     7     
     8     *p = 5;
     9     
    10     printf("c = %d
    ", c);  // c = 10
    11     
    12     return 0;
    13 }
    14 
    15 // 编译器 g++
    const 常量

        

      3)const 常量 与 宏定义

        相同点:

          c++中 const 常量 ≈ 宏定义;( const int a = 10; ≈ #define a 10 )

        不同点:

          const 是由编译器处理,编译器对 const 有 类型检查作用域检查

          宏定义 是由预处理器处理,只是单纯的文本替换

     1 #include <stdio.h>
     2 
     3 void f()
     4 {
     5     #define a 3
     6     const int b = 4;
     7 }
     8 
     9 void g()
    10 {
    11     printf("a = %d
    ", a);
    12     //printf("b = %d
    ", b);    // err
    13 }
    14 
    15 int main()
    16 {
    17     const int A = 1;
    18     const int B = 2;
    19     int array[A + B] = {0};
    20     int i = 0;
    21     
    22     for(i=0; i<(A + B); i++)
    23     {
    24         printf("array[%d] = %d
    ", i, array[i]);
    25     }
    26     
    27     f();
    28     g();
    29     
    30     return 0;
    31 }
    const常量 与 宏定义

      结论:--- 经典问题解析一

        1)const 常量的判断方法:

          1、只有用 字面量初始化的 const 常量才会进入符号表;

          2、使用其它变量初始化的 const 常量仍然是 只读变量;

          3、被 volatile 修饰的 const 常量不会进入符号表;

        2)const 引用类型 与 初始化变量的类型 

          相同:初始化变量成为只读变量;

          不同:生成一个新的只读变量;

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     const int x = 1;    // 只有用  字面量  初始化的const常量才进入符号表--- 此处x进入符号表,x是常量
     6     const int& rx = x;  // 编译器分配给常量x的内存地址的别名为 rx--- rx是只读变量
     7     
     8     int& nrx = const_cast<int&>(rx);    // 去除只读变量rx的只读属性 --- nrx
     9     
    10     nrx = 5;
    11     
    12     printf("x = %d
    ", x);          // 1
    13     printf("rx = %d
    ", rx);        // 5
    14     printf("nrx = %d
    ", nrx);      // 5
    15     printf("&x = %p
    ", &x);        // 0x7ffd8aed8f90
    16     printf("&rx = %p
    ", &rx);      // 0x7ffd8aed8f90
    17     printf("&nrx = %p
    ", &nrx);    // 0x7ffd8aed8f90    
    18     
    19     volatile const int y = 2;       // volatile 修饰的const常量不会进入符号表---y是只读变量
    20     int* p = const_cast<int*>(&y);  // 去除y的只读属性
    21     
    22     *p = 6;
    23     
    24     printf("y = %d
    ", y);  // 6
    25     printf("&y = %p
    ", &y);// 0x7ffd8aed8f94
    26     printf("p = %p
    ", p);  // 0x7ffd8aed8f94
    27     
    28     const int z = y;    // 用 其它变量 初始化const常量,仍是只读变量 --- z是只读变量
    29     
    30     p = const_cast<int*>(&z);   // 去除z的只读属性
    31     
    32     *p = 7;
    33     
    34     printf("z = %d
    ", z);  // 7
    35     printf("&z = %p
    ", &z);// 0x7ffd8aed8f98
    36     printf("p = %p
    ", p);  // 0x7ffd8aed8f98
    37     
    38     char c = 'c';
    39     char& rc = c;
    40     const int& trc = c; //const引用类型 与 初始化变量的类型不一致,则生成新的只读变量 --- trc为新的只读变量
    41 
    42     printf("c = %c
    ", c);      // c
    43     printf("rc = %c
    ", rc);    // c
    44     printf("trc = %c
    ", trc);  // c
    45     
    46     rc = 'a';
    47     
    48     printf("c = %c
    ", c);      // a
    49     printf("rc = %c
    ", rc);    // a
    50     printf("trc = %c
    ", trc);  // c
    51     
    52     return 0;
    53 }
    1)2)结论的代码展示

        3) 指针常量 Type * const pt (引用的本质)

          c++中没有引用数组的概念;(因为数组在内存中是一段连续的存储空间,然而引用数据并不满足这个要求)

    2 类中的 const(const 对象  和 const 成员函数)--- 经典问题解析二

      const 对象的特点:

        1)const修饰的对象为只读对象;

        2)只读对象的成员变量不可以修改;

        3)只读对象是编译阶段的概念,运行时无效;

        注:const 对象 不推荐使用;

      const 成员函数的特点:

        1)只读对象只能调用const成员函数;

        2)const成员函数 只能 调用const成员函数;

        3)const成员函数 不能 直接修改成员变量的值;(const 成员函数 使 this指针所指向的对象具有了只读属性)

        注:const 成员函数 在 声明与定义的时候必须都有 const;

     1 #include <stdio.h>
     2 
     3 class Test
     4 {
     5     int mi;
     6 public:
     7     Test(int i);
     8     Test(const Test& t);
     9     int getMi() const;
    10     void print();
    11 };
    12 
    13 Test::Test(int i)
    14 {
    15     mi = i;
    16 }
    17 
    18 Test::Test(const Test& t)
    19 {
    20     
    21 }
    22     
    23 int Test::getMi() const
    24 {
    25     //mi = 0; // error // const成员函数 不能 直接修改成员变量的值
    26     //print();// error // const成员函数 只能 调用const成员函数
    27     return mi;
    28 }
    29 
    30 void Test::print()
    31 {
    32     printf("v = %d
    ", mi);
    33 }
    34 
    35 int main()
    36 {
    37     /*
    38      * 1 const可以修饰类的对象 
    39      * 2 const修饰的对象为只读对象
    40      * 3 只读对象的成员变量不可以修改
    41      * 4 只读对象是编译阶段的概念,运行时无效
    42     */
    43     /*
    44      * 1 只读对象只能调用const成员函数
    45      * 2 const成员函数 只能 调用const成员函数
    46      * 3 const成员函数 不能 直接修改成员变量的值
    47     */
    48     const Test t(1);    
    49     printf("v = %d
    ", t.getMi()); // 只读对象只能调用const成员函数
    50 
    51     
    52     return 0;
    53 }
    const 对象 和 const 成员函数

        

  • 相关阅读:
    log日志框架和LocationAwareLogger问题
    Eclipse 各种小图标的含义
    自定义log4j日志级别
    在Tomcat配置JNDI数据源的三种方式
    mybatis中"#"和"$"的区别
    Postman用法简介-Http请求模拟工具
    mustache模板技术(转)
    VS的编译选项
    Java Service Wrapper简介与使用
    还活着
  • 原文地址:https://www.cnblogs.com/nbk-zyc/p/12310819.html
Copyright © 2011-2022 走看看