1. const的用法
1.1 const可以修饰什么?
1.1.1 普通变量
// 基本数据类型
const int a;
float const b; // const 写前写后都可以
1.1.2 指针变量
这里要区分顶层const和底层const,区分的方法:U型地(右边的*代表底层const)。
const int* a1; // 底层const,指针指向的变量的值不能改变,也是最常见的
int const* a2; // 也是底层const,和上面的共同点是const都在*左边
int* const a3; // 顶层const,指针的指向不能发生改变
关于顶层和底层的相关说明可以看这里。
1.1.3 对象及其成员变量、成员方法
class A {
const int mem_a_; // 和普通变量类似
const int Method_a1(); // 返回值类型是常量
int Method_a2() const; // 从编译器层面保证方法中不会修改类的成员变量
};
const A class_a;
在修饰成员方法的时候,要注意const对象是不能调用非const方法的,具体细节见为什么const对象只能调用const成员函数,而不能调用非const成员函数?。
需要注意的是,const成员方法只管顶层const,不管底层const,也就是说如果如果const成员变量类型是指针,那么只是其指向不能改,其中内容还是可以改的。
2. #define的用法
在预处理阶段,会对内容做简单替换,可以用来定义常量(字符串字面值、基本数据类型等),也可以接受传入参数但C++中不推荐使用宏,而推荐使用C++11中的constexpr,优点是只会在特定命名空间起作用(如果已经限定命名空间),而且可以对表达式在编译期就进行求值而不是在runtime才进行求值。
// 类型
#define CONST_STR "123"
#define CONST_INT 123
3. 区别
(1)const是在编译阶段进行替换的,会对类型进行语法检查,#define是在预处理阶段进行的,在预处理阶段是不会进行语法检查的(当然要得到可执行文件的话,肯定要经过编译,在编译阶段还是会出错的)。