详解 C++ 中 const 用法

微信搜索“编程笔记本”,获取更多信息
------------- codingbook2020 -------------

const(constant) 的英文释义是: 不变的; 固定的; 恒定的。const 关键字可以修饰一个类型,告诉编译器,这个类型的值是保持不变的,任何改变这种类型值的操作都是非法的。事实上,我们在编程的时候,如果确定某个值是恒定不变的,就应该为其加上 const 约束,从而避免错误地修改行为。

1. const 修饰普通类型变量

const int a = 1;
int b = a;          // 读值,正确
// a = 2;           // 写值,错误

int a = 1;前面加上 const关键字,那么 a 就被定义成了一个常量,所谓常量,就是更定不变的量、不能被修改的量。我们可以正常读取常量的值,比如 b = a;,但是任何修改常量的行为都是非法的,比如 a = 2;

再看下面的例子:

#include <iostream>

using namespace std;

int main() {
    const int a = 1;
    int* p = const_cast<int*>(&a);
    *p = 2;
    cout << "&a = " << &a << endl;
    cout << "p =  " << p << endl;
    cout << "a = " << a << " *p = " << *p << endl;

    return 0;
}

/*
运行结果:
&a = 0x7fff3a61c1e4
p =  0x7fff3a61c1e4
a = 1 *p = 2
*/

可以看到,虽然我们将 a 的地址从 const int*转换成了 int*,并对此地址中的值成功地进行了修改,但从运行结果来看,虽然 a 的地址和 p 相同,但是 a 的输出结果仍然是常量 1 ,而 *p 的输出结果却是我们修改的 2 。这一现象就是我们意想不到的行为。所以,当我们将某个量定义成常量时,就不应该通过任何途径去修改它的值,否则将会产生意想不到的结果。

2. const 修饰指针类型变量

const 修饰指针变量时有三种情况:

  • const 修饰的是指针,则指针本身不可变
int a = 1, b = 2;
int* const p = &a;
*p = 3;               // 修改指针指向的值,正确
// p = &b;            // 修改指针本身,错误

这种指针本身不可变,但其指向的内容可变的 const 称为顶层 const (top-level const)。

  • const 修饰的是指针指向的内容,则内容不可变
const int* p = 1;
int b = 2;
p = &b;              // 修改指针本身,正确
// *p = 3            // 修改指针指向的值,错误

这种指针本身可变,但其指向的内容不可变的 const 称为底层const (low-level const) 。

  • const 修饰指针及其指向的内容,则指针本身及其指向的内容均不可变
int a = 1, b = 2;
const int* const p = &a;
// *p = 3;                  // 修改指针指向的值,错误
// p = &b;                  // 修改指针本身,错误

在这种情况下,指针本身的值及其指向的值均不可变。

3. const 修饰函数参数

int sum(const int a, const int b) {
    int s = a + b;
    // a = 1;         // 错误,底层 const
    // b = 1;         // 错误,底层 const
    return s;
}

int sum(int* const p1, int* const p2) {
    int s = *p1 + *p2;
    // p1 = &s;       // 错误,顶层 const
    // p2 = &s;       // 错误,顶层 const
    return s;
}

const 修饰函数参数的情况和 const 修饰普通变量和指针的情况相同。

4. const 修饰函数返回值

  • const 修饰内置类型返回值,与不加 const 修饰无异。
#include<iostream>

using namespace std;
 
const int f1()
{
    return 1;
}
 
const double f2()
{
    return 1.23;
}
 
int main()
{
    int v1 = f1();
    double v2 = f2();
    cout << "v1 = " << v1 << " v2 = " << v2 << endl;

    v1 += 1;
    v2 += 1;
    cout << "v1 = " << v1 << " v2 = " << v2 << endl;

    return 0;
}

/*
运行结果:
v1 = 1 v2 = 1.23
v1 = 2 v2 = 2.23
*/

从示例可以看出,返回值仍可以修改,并不是一个常量。

  • const 修饰指针返回值,是底层 const。
#include<iostream>

using namespace std;

int a = 1;

const int* f()
{
    return &a;
}
 
int main()
{
    auto p = f();
    //*p = 2;        // 错误,底层 const
    p = &a;          // 正确

    return 0;
}

5. const 修饰类的成员函数

成员函数用 const 修饰,是为了防止调用对象的值被修改。

#include<iostream>

using namespace std;

class A {
public:
    A(int a) : m(a) {}
    int get_m(int a) const {
        // m += 1;               // 错误,不能修改对象的字段
        return m;
    }
private:
    int m;
};
 
int main()
{
    A a(1);
    cout << a.get_m() << endl;    // 1
    return 0;
}

点击下方图片关注我,或微信搜索**“编程笔记本”**,获取更多信息。
在这里插入图片描述

发布了19 篇原创文章 · 获赞 0 · 访问量 213
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览