const关键字
- const名叫常量限定符,用来限定特定变量,以通知编译器该变量是不可修改的。习惯性的使用const,可以避免在函数中对某些不应修改的变量造成可能的改动。
const和#define的区别
1 | const int a = 0; |
- 编译器处理方式不同
- #define在预处理阶段展开。
const在编译期间使用。
- #define在预处理阶段展开。
- 类型和安全检查方式不同
- #define宏没有类型,不做任何类型检查,仅仅是展开。
const常量有具体的类型,在编译阶段会执行类型检查。
- #define宏没有类型,不做任何类型检查,仅仅是展开。
- 存储方式不同
- define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
const常量会在内存中分配(可以是堆中也可以是栈中)。
- define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。
- 作用域
- #define只能定义全局变量 const可以定义类内专属常量。
1
2
3
4
5
6
7class A{
public:
const int a = 9;
};
A obj;
cout << obj.a << endl;//ok
cout << a << endl;//error!only visible in class
- #define只能定义全局变量 const可以定义类内专属常量。
- const的几个优点
- 编译器可以检查const类型 #define只是进行替换。
- 调试器可以对const进行调试,但不能对宏变量进行调试。
- 对于常量,尽量使用const、enum代替#define
- 对于函数宏定义,尽量使用inline函数代替#define
const的内存分配
- 对于基础类型(整数,浮点数,字符) 系统不会给const变量开辟空间,会将其放到符号表中。
- 对const变量取地址的时候 系统就会给它开辟空间。
- 当用变量给const变量赋值时,系统直接为其开辟空间而不会把它放入符号表中。
- const 自定义数据类型(结构体、对象) 和数组系统会分配空间。
主要功能和用法
- 在class外部修饰全局变量
1
2
3
4
5
6
7
8
9
10
11
12const int a = 1;
using namespace std;
extern const int a;
int main()
{
int *p = (int *)(&a);
*p = 8;//error!Exception has occurred.Segmentation fault
cout << "a=" << a << endl;
cout << "*p=" << *p;
return 0;
} - 修饰namespace作用域中的常量
1
2
3
4
5
6
7
8
9
10
namespace hqin{
const int a = 0;
} // namespace hqin
int main()
{
hqin::a = 1; //error: assignment of read-only variabl 'hqin::a'
return 0;
} - 修饰文件、函数或者作用域中被声明为static的对象
- 不希望改变static变量时使用。
- 通常情况下如果不希望改变文件指针、函数内部等更改数据,就命名为const类型
1
2
3
4
5
6
7
8
9
10
11
12template<typename T>
class A{
public:
//不希望改变x,y,函数内部也不希望改变data
inline T sum (const T& x, const T& y) const{
return x + y;
}
};
A<complex<int>> test = A<complex<int>>();
complex<int> a(1,1);
complex<int> b(1,1);
cout << test.sum(a,b); - 修饰class内部的static和non-static成员变量
1
2
3
4
5class A{
public:
const int x = 0;
const static int y = 0;
}; - 修饰指针、指针所指物
1
2
3
4
5int * const p1; // p1:只读 *p1:变量
const int *p2; // p2:变量 *p2:只读
int const *p3; // p3:变量 *p3:只读
int const * const p4; // p4:只读 *p4:只读
const int * const p5; // p5:只读 *p5:只读
const初始化
在c++ 11 之前,普通变量、常量(const)、静态(static)、静态常量(static const)的初始化和声明如下表所示。
type 声明时初始化 初始化列表初始化 构造函数内初始化 类外初始化 普通变量 x √ √ x (整型除外) const x √ x x static x x x √ static const x x x √ c++ 11之后,如下表所示。
type 声明时初始化 初始化列表初始化 构造函数内初始化 类外初始化 普通变量 √ √ √ x (整型除外) const x √ x x static x x x √ static const x x x √