• c++const关键字---15


    原创博文,转载请标明出处--周学伟   http://www.cnblogs.com/zxouxuewei/

    const是一个C++语言的限定符,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。

    1. 修饰常量

    用const修饰的变量是不可变的,以下两种定义形式在本质上是一样的:

    const int a = 10;
    int const a = 10;

    2. 修饰指针

    如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
    如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
    因此,推荐使用int const* p,而不是使用const int* p(虽然两者意义完全一样),这样更容易理解。

    int a = 10;
    const int* p = &a;            // 指针指向的内容不能变
    int const* p = &a;            // 同上
    int* const p = &a;            // 指针本身不能变
    const int* const p = &a;      // 两者都不能变
    int const* const p = &a;      // 同上

    3. 修饰引用

    以下两种定义形式在本质上是一样的:

    int a = 10;
    const int& b = a;
    int const& b = a;

    4. 修饰函数参数

    用const修饰函数参数,传递过来的参数在函数内不可以改变。

    void func (const int& n)
    {
         n = 10;        // 编译错误 
    }

    5. 修饰函数返回值

    用const修饰函数返回值的含义和用const修饰普通变量以及指针的含义基本相同。

    const int* func()   // 返回的指针所指向的内容不能修改
    {
        // return p;
    }

    6. 修饰类成员变量

    用const修饰的类成员变量,只能在类的构造函数初始化列表中赋值,不能在类构造函数体内赋值。

    复制代码
    class A
    {
    public:
        A(int x) : a(x)  // 正确
        {
             //a = x;    // 错误
        }
    privateconst int a; };
    复制代码

    7. 修饰类成员函数

    用const修饰的类成员函数,在该函数体内不能改变该类对象的任何成员变量, 也不能调用类中任何非const成员函数。

    复制代码
    class A
    {
    public:
        int& getValue() const
        {
            // a = 10;    // 错误
            return a;
        }
    
    private:
        int a;            // 非const成员变量
    };
    复制代码

    8. 修饰类对象

    用const修饰的类对象,该对象内的任何成员变量都不能被修改。
    因此不能调用该对象的任何非const成员函数,因为对非const成员函数的调用会有修改成员变量的企图。

    复制代码
    class A
    {
     public:
        void funcA() {}
        void funcB() const {}
    };
    
    int main
    {
        const A a;
        a.funcB();    // 可以
        a.funcA();    // 错误
    
        const A* b = new A();
        b->funcB();    // 可以
        b->funcA();    // 错误
    }
    复制代码

    9. 在类内重载成员函数

    class A
    {
    public:
        void func() {}
        void func() const {}   // 重载
    };

    10. const与宏定义的区别

    const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误。
    const常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
    另外,编译器通常不为const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

    #define PI 3.1415926535
    const double PI = 3.1415926535;

    11. const_cast

    const_cast运算符用来修改类型的const或volatile属性。
    一、常量指针被转化成非常量的指针,并且仍然指向原来的对象;
    二、常量引用被转换成非常量的引用,并且仍然指向原来的对象。

    void func()
    {
        const int a = 10;
        int* p = const_cast<int*> (&a);
        *p = 20;
        std::cout<<*p;    // 20
        std::cout<<a;     // 10, 原因见第10部分
    }

     例程如下:

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    class kstruction
    {
    public:
        kstruction(const string str,const int val,string descript);
        ~kstruction();
        void display();
        void change(const string des);//const修饰成员函数的参数
        int function()const ;//const修饰成员函数的返回值
        int value;
    private:
        const string name;//const修饰成员变量
        const  int age;
        string description;
        
    };
    
    kstruction::kstruction(const string str,const int val,string descript)
        :name(str),age(val)
        {
            //用const修饰的类成员变量,只能在类的构造函数初始化列表中赋值,不能在类构造函数体内赋值。
            //name = str;
            //age  = val;
            description = descript;
            cout <<"construction"<<endl;
        }
    
    kstruction::~kstruction()
    {
        cout <<"Destructiong"<<endl;
    }
    
    void kstruction::display()
    {
        cout <<"name = "<<name<<" ,age = "<<age<<" ,description = "<<description<<endl;
    }
    
    void kstruction::change(const string des)
    {
        //用const修饰函数参数,传递过来的参数在函数内不可以改变。
        //str = "wanghuixi";
        description = des;
    }
    
    int kstruction::function()const 
    {   
        //用const修饰的类成员函数,在该函数体内不能改变该类对象的任何成员变量, 也不能调用类中任何非const成员函数。
        //description = "software";
    }
    
    int main(int argc, char const *argv[])
    {
        
        kstruction struct1("zhouxuewei",23,"software");
     
        struct1.change("hardware");
        struct1.function();
    
        struct1.display();
    
        const kstruction conststruct;//const修饰类的对象
        //用const修饰的类对象,该对象内的任何成员变量都不能被修改。
        conststruct.value = 100;
        return 0;
    } 
  • 相关阅读:
    Python环境管理(虚拟环境)/包管理工具
    Java面试题集锦
    python跟踪脚本运行过程(类似bash shell -x)
    【ClickHouse问题】更新表字段类型为Nullable(Int32)的列值,最终结果都是固定一个值:93147008???
    【ClickHouse】0:clickhouse学习4之表相关操作
    【ClickHouse】0:clickhouse学习3之时间日期函数
    【ClickHouse】0:clickhouse学习2之数据类型
    【ClickHouse】0:clickhouse学习1之数据引擎(数据库引擎,表引擎)
    【ClickHouse】7:clickhouse多实例安装
    【ClickHouse】6:clickhouse集群高可用
  • 原文地址:https://www.cnblogs.com/zxouxuewei/p/6581467.html
Copyright © 2020-2023  润新知