美文网首页
C++<第二十三篇>:常量运算符

C++<第二十三篇>:常量运算符

作者: NoBugException | 来源:发表于2022-01-24 14:11 被阅读0次

    在类中,如果你不希望某些数据被修改,可以使用const关键字加以限定。const 可以用来修饰成员变量和成员函数。

    (1)const成员变量

    const成员变量又称 常成员变量,简称 常量

    常量必须在定义的时候就初始化,否则编译器会报错。

    错误的写法:

    const int a;
    

    正确的写法:

    const int a = 10;
    

    除此之外,常量不可变,如果强制给他重新赋值,那么编译器会报错。

    (2)const成员函数

    Student.h文件

    #include <iostream>
    
    class Student
    {
    private:
        int16_t mScore; // 成绩
    
    public:
        void setScore(int score);
        int getScore() const;
    };
    

    Student.cpp文件

    #include "Student.h"
    
    void Student::setScore(int score)
    {
        mScore = score;
    }
    
    int Student::getScore() const
    {
        return mScore;
    }
    

    在 getScore 函数后面添加const关键字,这样的函数叫做 const成员函数,即 常成员函数

    编译器不允许在 常成员函数 内修改成员变量的值。

    getScore 函数的功能很简单,仅仅是为了获取成员变量的值,没有任何修改成员变量的企图,所以加了 const 限制,这是一种保险的做法,同时也使得语义更加明显。

    (3)常量返回值

    Student.h文件

    #include <iostream>
    
    class Student
    {
    private:
        int16_t mScore; // 成绩
    
    public:
        void setScore(int score);
        const int getScore();
    };
    

    Student.cpp文件

    #include "Student.h"
    
    void Student::setScore(int score)
    {
        mScore = score;
    }
    
    const int Student::getScore()
    {
        return mScore;
    }
    

    以上代码,将 const 放在函数返回值类型的前面,这样的函数的返回值就是常量整数类型。

    需要注意和 常成员函数 的区别。

    (4)const对象(常对象)

    在 C++ 中,const 也可以用来修饰对象,称为 常对象。一旦将对象定义为常对象之后,就只能调用类的 const 成员(包括 const 成员变量和 const 成员函数)了。

    const Student student;
    

    student对象是 常对象,此时student只能调用 常量常成员函数 了。

    (5)常量指针与指针常量

    常量指针:如果在定义指针变量的时候,指针变量前用const修饰,被定义的指针变量就是指向常量的指针变量,指向常量的指针变量称为常量指针,格式如下

    const int* p = &a; // * p 是常量
    int const* p = &a; // * p 是常量
    

    以上两种写法是一致的。常量指针本质上是一个指针。

    指针常量:顾名思义它就是一个常量,但是是指针修饰的,格式如下

    int* const p = &a; // p 是常量
    

    指针常量本质上是一个常量,所以p必须在定义的时候初始化。

    两者可以结合使用,即指向常量的指针常量:

    const int* const p = &a;
    
    (6)常量引用

    先看下非常量引用的代码:

    int a = 10;
    int& ref = a;
    

    引用 ref 指向变量 a;

    常量引用既可以指向非常量,也可以指向常量:

    int a = 10;
    const int& ref = a; // 指向非常量
    ---------------------------------------
    const int a = 10;
    const int& ref = a; // 指向常量
    

    常量引用不可以重新指向变量。

    但是,非常量引用不可以指向常量,如下代码是错误的:

    const int a = 10;
    int& ref = a;
    
    (7)当临时变量遇到非常量引用
    int a = 3, b = 4;
    int& ref1 = a;
    int& ref2 = b;
    

    以上代码是应用的常规写法,是没问题的。但是如果是这样呢?

    int a = 3, b = 4;
    int& ref = a + b;
    

    a+b 之后是一个临时变量,如果直接使用 ref 引用指向这个临时变量是错误的,编译器会报错。

    临时变量 如果一定是被引用指向的话,那必须是被一个常量引用指向,即:

    const int& ref = a + b;
    

    举一个例子:

    void function(const int& ref) 
    {
        cout << ref << endl;
    }
    
    int main()
    {
    
        int a = 3, b = 4;
    
        function(a + b);
    
        cout << a << endl;
    
        return 0;
    }
    

    函数 function 的形式参数之所以写成常量,是因为传入的实参为 a + b,即临时变量,由于C++语法的限制,这种情况应该将 函数 function 参数加上 const 关键字。

    常量不可以成为左值,如下代码是错误的,编译器不会承认:

    void function(const int& ref) 
    {
        ref = 3;
    }
    

    总之,一个函数的形式参数是否添加const,取决于形参的行为,常量不能称为左值,左值是一个变量,而不是常量。

    (7)函数后面添加const

    非静态成员函数后面加const,类似如下函数:

    class Base { 
    
    public:
        void setA(int a) const
        {
            this->mA = a;
        }
    private:
        int mA;
    };
    

    表示成员函数隐含传入的this指针为 const指针,
    决定了在该成员函数中,任意修改它所在的类的成员的操作都是不允许的,因为隐含了对this指针的const引用。
    就是说不会改变对象中成员变量的数值。

    以上函数中 this->mA = a 是不被允许的。

    (8)C 和 C++ 有关常量的一个区别

    先看下代码:

    const int a = 10;
    int* p = &a;
    *p = 2;
    
    cout << a << endl;
    cout << *p << endl;
    

    以上代码在 C 中是没问题的,打印结果是:

    2
    2
    

    但在C++下会提示, const int* 类型的值不能用于初始化 int* 类型的实体 以及 无法从 const int* 转成 int* 错误,这里需要做一下强制转换:

    int* p = (int*) & a;
    

    C++的输出结果是:

    10
    2
    

    在 C 中编译器会为常量分配内存;
    在 C++ 中对于基本类型的常量,编译器并不为其分配存储空间,编译器会把它放到 符号表,当取符号常量的地址等操作时,将强迫编译器为这些常量分配存储空间,编译器会重新在内存中创建一个它的拷贝, 通过地址访问到的就是这个拷贝,而非原始的符号常量;

    除此之外,C 的常量不能用来确定数组的大小,但是 C++ 的常量是可以用来确定数组的大小的,如下:

    const int size = 10;
    int name[size];
    

    [本章完...]

    相关文章

      网友评论

          本文标题:C++<第二十三篇>:常量运算符

          本文链接:https://www.haomeiwen.com/subject/deqvhrtx.html