0%

const详解

const

const 用于定义常量、声明常量引用以及修饰成员函数。const 的作用是告诉编译器这个东西是不可修改的,即它的值在初始化后不能再被修改。

编译器通常不为普通的const常量分配内存空间,而是将他们保存在符号表中。

1. 定义常量
1
const int x = 5;

定义了一个常量 x,其值为 5。一旦定义,其值就无法修改。

2. const和引用

const修饰的引用称为”常用引用“,常量引用不能直接修改所引用的对象。

1
2
3
4
const int ci = 1024;//ci是一个int型的常量
const int &r1 = ci;//正确,r1是一个常量引用,并且r1本身也是一个常量
r1 = 42;//错误,引用被const限制了,不能修改所引用对象的值了
int &r2 = ci;//错误,试图让一个非常量引用指向一个常量对象
3. const和指针
  1. 常量指针:指针指向的对象不可变,但指针本身的值可以改变。

    1
    2
    3
    4
    5
    6
    int x = 5;
    const int* ptr = &x; // ptr 是一个指向整型常量的指针,它所指向的对象不能被修改,但可以改变指针的值

    // *ptr = 10; // 错误,不能修改 ptr 所指向的对象的值
    int y = 10;
    ptr = &y; // 可以修改指针 ptr 的值,使其指向不同的对象
  2. 指针常量:指针本身的值不可变,但指针所指向的对象可以改变。

    1
    2
    3
    4
    5
    int x = 5;
    int* const ptr = &x; // ptr 是一个指向整型的常量指针,它的值不能改变,但可以修改其指向的对象

    *ptr = 10; // 可以修改 ptr 所指向的对象的值
    // ptr = &y; // 错误,无法修改指针 ptr 的值
4. const和类对象
  1. const成员变量:

    const 成员变量是指在类中声明为常量的数据成员。一旦被初始化,其值就不能再修改。它们只能在类的构造函数初始化列表中初始化,而不能在构造函数体中赋值。

  2. const成员函数:

    const只能限定类的成员函数,表示该函数不会修改类的成员变量,除非成员变量被 mutable 修饰符修饰

const限定后,该成员函数不允许修改类的数据成员,也不允许调用非const函数,即使该函数没有修改类的数据成员,只要没有声明成const,就不能调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

class MyClass {
public:
// 构造函数初始化 const 成员变量
MyClass(int x): constValue(x) {}

int getValue() const {
// 这是一个常量成员函数,不能修改类的成员变量
return value;
}

void setValue(int newValue) {
value = newValue;
}

private:
const int constValue;
};

int main() {
const MyClass obj(10);
std::cout << "Value: " << obj.getValue() << std::endl; // 合法,调用常量成员函数
// obj.setValue(5); // 错误,常量对象不能调用非常量成员函数
obj.constValue = 5; // 错误,不能修改 const 成员变量的值
return 0;
}
constexper

constexpr 是 C++11 引入的关键字,用于声明“常量表达式”。

常量表达式是在编译时就可以求值的表达式,即它的值可以在编译时被确定。

constexpr 可以用于变量、函数、构造函数以及类的成员函数,用于指示它们在编译时就可以被计算出来,而不是在运行时计算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//5是一个常量表达式
constexpr int x = 5;

//square是一个constexpr函数
constexpr int square(int x){
return x * x;
}

class Circle {
private:
constexpr static double PI = 3.14159;
double radius;
public:
constexpr Circle(double r) : radius(r) {}
constexpr double getArea() const {
return PI * radius * radius;
}
};

使用 constexpr 可以使得程序在编译时进行更多的优化,提高程序的性能。