CPULSPULS项目学习1

const那些事

  1. const作用

    • 定义常量
    • 类型检查
      1. const#definde宏定义的区别:const常量具有类型,编译器可以进行安全检查;#define宏定义没有数据类型,只是简单的字符串替换,不能进行安全检查。[issue]https://github.com/Light-City/CPlusPlusThings/issues/5
      2. const只有在修饰枚举和整型变量时才能作为常量表达式
    • 防止修改,起保护作用,增加程序健壮性
    • 可以节省空间,避免不必要的内存分配

      const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。

  2. const对象默认为文件局部变量
    注意:非const变量默认为extern。要使const变量能够在其他文件中访问,必须在文件中显式地指定它为extern。
    小结:未被const修饰的变量不需要extern显式声明!而const常量需要显式声明extern,并且需要做初始化!因为常量在定义后就不能被修改,所以定义时必须初始化。

    //file1.cpp
    #include<iostream>
    using namespace std;
    extern const int a;
    extern int b;
    int main()
    {
        cout<<a<<b<<endl;
        return 0;
    }
    //file2.cpp
    extern const int a = 10;//需要显式声明并且初始化
    int b;//不需要显式声明
    
  3. 指针与const

    const char * a; //指向const对象的指针或者说指向常量的指针。
    char const * a; //同上
    char * const a; //指向类型对象的const指针。或者说常指针
    const char * const a; //指向const对象的const指针。  
    

    小结:如果const位于的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于的右侧,const就是修饰指针本身,即指针本身是常量。

    1. 指向常量的指针
    const int *ptr;//const定义int类型,所以ptr不用赋初值且ptr可
                    //改变指向的对象;
    *ptr = 10;//error
    

    允许把非const对象的地址赋给指向const对象的指针:

    const int *ptr;
    int a = 10;
    ptr = &a;//ok。但是不能通过ptr指针来修改a的值
    

    不能使用指向const对象的指针修改基础对象,如果该指针指向了非const对象,可用其他方式修改其所指的对象:

    const int *ptr;
    int a = 10;
    ptr = &a;
    int *p = &a;
    *p = 20;//用一个普通指针指向该基础对象,使用普通指针修改即可。
    
    1. 常指针
      const指针必须进行初始化,且const指针的值不能修改
    #include<iostream>
    using namespace std;
    int main()
    {
        int a=10,b = 11;
        int* const ptr = &a;
        *ptr = 20;//ok,可以改变基础变量的值
        cout<<*ptr<<endl;
        ptr = &b;//error,不可以改变指向
        return 0;
    }
    

    不能让常指针指向const对象

  4. 函数中使用const

    • const修饰函数返回值
    const int func1();
    
    const int* func1();//指针指向的内容不变。???什么情况下用??
    
    int* const func1();//指针本身不变。???什么情况下用??
    
    • const修饰函数参数
      (1)传递过来的参数及指针本身在函数内不可变,无意义!
    void func(const int var); // 传递过来的参数不可变
    void func(int *const var); // 指针本身不可变
    

    (2)参数指针所指内容为常量不可变

    //src是输入参数,dst是输出参数
    void StringCopy(char *dst, const char *src);
    

    (3)参数为引用,为了增加效率同时防止修改。

    void func(const A &a)//引用传递有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可
    

    小结:对于非内部数据使用引用传递会提高效率,对内部数据“引用传递”和“值传递”效率差不多,因为内部数据不存在构造、析构的过程,且复制较快。对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性

  5. 类中使用const
    在一个类中,任何不会修改数据成员的函数都应该声明为const类型。使用const关键字进行说明的成员函数,称为常成员函数只有常成员函数才有资格操作常量或常对象,没有使用const关键字明的成员函数不能用来操作常对象

    • 类中的const成员变量必须通过初始化列表进行初始化
    • const对象只能访问const成员函数,非const对象可以访问任意的成员函数,包括const成员函数。
    • const对象默认调用const成员函数。

    const成员变量:只读变量,只能通过初始化列表初始化
    const成员函数:不能直接改变成员函数的值,智能调用const成员函数
    const对象只能调用const成员函数

    • const成员变量可以用以下方式初始化(c++11)
     #include<iostream>
     #include<string>
     using namespace std;
     class apple
     {
         public:
         apple();
         static const int a = 10;//内部直接初始化
         int b = 20;
         const int c = 30;//内部直接初始化
         static const int d;
         static int num;//static静态成员变量不能在类的内部初始化。
                        //在类的内部只是声明,定义在类定义体的外部
     };
     apple::apple(){}
     const int apple::d = 40;//外部初始化
     int main()
     {
         apple a1;
         cout<<a1.a<<endl;
         cout<<a1.b<<endl;
         cout<<a1.c<<endl;
         cout<<a1.d<<endl;
         return 0;
     }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值