zoukankan      html  css  js  c++  java
  • C/C++中const用法

    1、简介

    const是C/C++中的一个关键字,是一个类型限定符,const为constant的缩写,含义为不变的,不易改变的,使用该关键字能限定一个变量不允许改变,产生静态作用,在一定程度上能提高程序的安全性和可靠性。

    2、const修饰普通类型变量

    const int n = 1;  //const类型对象    
    int m = n;  //正确
    n = 3;  //错误,n为const限定

    n被定义为一个常量,可以将n的值赋给m,但是不能给n再次赋值,n被编译器认为是一个常量,其值不允许再次修改。

    int x = 2;  //无const限定类型对象
    const int *p = &x;  //const限定类型对象
    *p = 3;  //错误,*p的类型为const限定

    *p被限定为const类型,不能够再次赋值。

    3、const修饰指针变量

    const关键字修饰指针变量具有以下三种情况:

    • const修饰指针指向的内容,该内容为不可变量;
    • const修饰指针,该指针为不可变量;
    • const修饰指针和指针指向的内容,该指针和指针指向的内容都为不可变量。

    对于第一种情况,示例如下:

    const int *p = 1;

    p为int类型指针变量,其所指向的内容1不可改变,简称左定值,由于const位于*号的左边。

    对于第二种情况,示例如下:

    int a = 1;
    int * const p = &a;
    *p = 2;  //正确
    int b = 2;
    p = &b;  //错误

    int类型指针变量p被限定为const,因此p指向的内存地址不能够改变,但是内容可以被改变,简称右定向,因为const位于*号的右边。

    对于第三种情况,则是第一种情况和第二种情况的组合,示例如下:

    int a = 1;
    const int * const p = &a;

    int类型指针变量p所指向的内容以及指向都已经固定,为不可变量。

    对于上面的三种情况,根据const位于*号位置的不同,简单记忆为:左定值,右定向,const修饰不变量。

    4、const修饰函数参数

    const修饰函数参数大致可以分为三种情况:

    第一种情况为,值传递的const修饰传递,这种情况一般不需要const修饰,因为函数会自动产生临时变量复制实参值,示例如下:

    #include <iostream>
    
    using namespace std;
    
    void fun(const int a)
    {
      cout << a;
      //a++;  //错误,a不能改变      
    }
    
    int main (void)
    {
      fun(1);
      return 0;    
    }

    第二种情况为,const参数为指针时,能够防止指针被意外篡改,示例如下:

    #include <iostream>
    
    using namespace std;
    
    void fun(int *const p)
    {
      cout << *p << " ";
      *p = 2;    
    }
    
    int main(void)
    {
      int a = 1;
      fun(&a);
      cout << a;  //a为2
      return 0;        
    }

    第三种情况为,自定义数据类型的参数传递,需要临时对象复制参数,对于临时对象的构造,需要调用构造函数,比较浪费时间,可以采用const外加引用传递的方式,示例如下:

    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    public:
      Test() {}
      Test(int _m):_cm(_m) {}
      int get_cm() const
      {
           return _cm;          
      }
    
    private:
        int _cm;
    };
    
    void fun(const Test& _tt)
    {
        cout << _tt.get_cm();
    }
    
    int main(void)
    {
        Test t(2);
        fun(t);  //结果输出2
        return 0;
    }

    5、const修饰函数返回值

    对于const修饰返回值,主要分三种情况,如下:

    第一种情况为,const修饰内置类型的返回值,修饰与不修饰返回值作用一样,示例如下:

    #include <iostream>
    
    using namespace std;
    
    const int fun1(void)
    {
        return 1;
    }
    
    int fun2(void)
    {
        return 2;
    }
    
    int main(void)
    {
        int a = fun1();
        int b = fun2();
    
        cout << a << " " << b;
        return 0;
    }

    第二种情况为,const修饰自定义类型作为返回值,此时返回的值不能作为左值使用,不能被赋值,也不能被修改。

    第三种情况为,const修饰返回的指针或者引用,是否返回一个const指向的指针,取决于我们想让用户干什么。

    6、const修饰类成员函数

    使用const修饰类成员函数,其目的是为了防止成员函数修改被调用对象的值,如果我们不想修改一个调用对象的值,那么,对象内的所有成员函数都应当声明为const成员函数,示例如下:

    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    public:
      Test() {}
      Test(int _m):_cm(_m) {}
      int get_cm() const  //const修饰成员函数
      {
           return _cm;          
      }
    
    private:
        int _cm;
    };
    
    void fun(const Test& _tt)
    {
        cout << _tt.get_cm();
    }
    
    int main(void)
    {
        Test t(2);
        fun(t);
        return 0;
    }

    Test类中的成员函数get_cm使用了const进行修饰,如果去掉了const修饰的话,函数fun()传递的const _tt即使没有改变对象的值,编译器也认为函数会改变对象的值,因此,一般按照要求将所有的不需要改变对象内容的成员函数使用const进行修饰。

    当有成员函数想要修改对象中的某个成员时,可以使用关键字mutable修饰该成员,被mutable修饰的成员可以处于不断变化,如下例子:

    #include <iostream>
    
    using namespace std;
    
    class Test
    {
    public:
        Test() {}
        Test(int _m, int _n):_cm(_m),_cn(_n) {}
        void func() const
        {
            _cm++;  //错误
            _cn++;  //正确
        }
    
    private:
        int _cm;
        mutable int _cn;
    };
    
    int main(void)
    {
        Test t(1, 2);
        return 0;
    }

    Test类中的func()成员函数被限定为const类型,在func()成员函数中修改成员_cm和_cn的值,使用_cm++修改_cm的值将会报错,因为_cm成员并没有使用mutable关键字进行修饰。

    原文地址:

    https://www.cnblogs.com/Forever-Kenlen-Ja/p/3776991.html

  • 相关阅读:
    迭代器和生成器
    装饰器进阶
    闭包和装饰器
    函数的嵌套
    函数的参数
    什么是粘包现象
    模拟ssh远程命令执行
    客户端与服务端代码bug修复和加入循环
    用socket实现简单的套接字通讯
    网络编程之客户端和服务端,
  • 原文地址:https://www.cnblogs.com/Cqlismy/p/13549666.html
Copyright © 2011-2022 走看看