- 一、const修饰普通变量
- 二、const修饰指针
- 三、const修饰函数返回值
- 四、const修饰类的成员函数
- 五、C和C++中const的区别
- 六、理解const修饰的是最近的类型
- 七、const与非const之间相互赋值的情况
一、const修饰普通变量
以下两点是某些const类型不能转换的根本原因
- 杜绝直接修改:const变量不能作为左值
- 杜绝间接修改:(C++中)const变量的地址不能泄露给一个非const类型的指针或引用
二、const修饰指针
int a = 10; //指针指向的内容不能修改 int const* p1 = &a; //指针不能指向别的地址 int *const p2 = &a; //两者都不能修改 int const * const p3 = &a;
三、const修饰函数返回值
const char * GetString(void); //如下语句将出现编译错误: //char *str = GetString(); //正确的用法是 const char *str = GetString();
//以下两个语句没有区别,加const没有意义 int GetInt(void); const int GetInt(void);
四、const修饰类的成员函数
class People
{
public:
int talk(void);
int eat(void) const; // const 成员函数
private:
int m_age;
};
int People::eat(void) const
{
++m_age; // 编译错误,企图修改数据成员m_num
talk(); // 编译错误,企图调用非const函数
return m_age;
}
const类对象只能调用const成员函数
- C++对于类型的检测很严格,如以下代码,在C++不能通过编译
int main()
{
const int a = 10;
int *p = &a; //在C语言中可以通过指针修改const变量,但是在C++不允许
*p = 11;
return 0;
}
- C语言中的const是个变量,const只存在于编译期,编译器会检查该变量是否被当作左值;
- C语言中const全局变量存储在只读区,const局部变量存储在栈区;
- C++中,对于基本类型const变量,使用字面量初始化该变量时,将变量放入符号表,此时不会分配内存,如果对它取地址,则会开辟一个新的空间,也就是说会创建一个临时变量,返回临时变量的地址;
- C++中,对于基本类型const变量,使用另一个变量初始化该变量时,会给该变量分配内存;
- C++中,对于const自定义类型和类对象,也会分配内存。
- C中const变量可以不初始化,但是C++中const必须初始化
可以理解为const修饰类型和表达式,修饰的类型就是离const最近的类型,去掉类型和const就是const修饰的表达式,该表达式不可修改。
const int *e; //const修饰的是int,e指向的变量不可修改
int const *f; //int离const最近,所以情况同上
int *const g = nullptr; //const修饰的是int *,g本身不可修改
const int **a; //const修饰的是int,
int const **b; //离const最近的是int,情况同上
int *const *c; //离const最近的是int *,一级指针不可修改
int **const d = nullptr; //const修饰的是int **,二级指针不可修改
七、const与非const之间相互赋值的情况
const int a = 10;
int b = 10;
b = a; //合法,int <-- const int
a = b; //不合法,const int <-- int
const int a = 10;
int b = 10;
const int *c = &a; //合法,const int* <-- const int*
int *d = &a; //不合法,int* <-- const int*
const int *e = &b; //合法,const int* <-- int*
int *f = &b; //合法,int* <-- int*
const int *c = nullptr;
int *d = nullptr;
int *const e = nullptr;
int **f = nullptr;
const int **g = nullptr;
int *const *h = nullptr;
int **const i = nullptr;
f = &c; //不合法,int** <-- const int**
f = &d; //合法,int** <-- int**
f = &e; //不合法,int** <-- int*const*
g = &c; //合法,const int** <-- const int**
g = &d; //不合法,const int** <-- int**
g = &e; //不合法,const int** <-- int*const*
h = &c; //不合法,int*const* <-- const int**
h = &d; //合法,int*const* <-- int**
h = &e; //合法,int*const* <-- int*const*
总结一下,就是const是限制,为了保证语言的安全性,限制可以增加但是不能减少。例外是当const修饰的表达式是多级指针的时候,转换的左右两边都必须有const,如下
//不合法,const int** <-- int** //不合法,int** <-- const int**



