“深入解析”这一词只是为了吸引大家的眼球,这里我主要说说自己的理解。既然是深入解析,那也要有一定的见解才好,不然贻笑大方。
Const顾名思义,就是常量,常量是什么,那就是不能轻易改变,注意是轻易(用const_cast可以强制转化)。我们主要从这几个方面入手解析:#define和const、const指针类型和普通数据类型、普通const函数、类的const成员函数和成员变量。
一、#define。宏是对复杂内容替换以后的简单文本,为了简单易读。typedef常用来定义一个标识符及关键字的别名,就是一个类型的同义。如:#define PI 3.1415926,typedef int A,A就和int是同义词。当然这不是重点,大家都知道(我的毛病就是喜欢把所有关联的知识点放到一起,因为记忆英语单词我也是这么干的)。我们更关心的是#define和const的区别:
- 编译器处理方式不同。#define是在预处理阶段展开(编译),const常量是编译运行阶段使用。
- 类型和安全检查不同。#define没有类型,没有类型检查,只是简单的展开,const有数据类型,在编译运行阶段检查类型。
- 存储方式不同。define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存,const常量会在内存中分配(可以是堆中也可以是栈中)。
- const 可以节省空间,避免不必要的内存分配。如程序
const一开始就分配了内存,而#define没有。 const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而 #define定义的常量在内存中有若干个拷贝。#define M 12.56 const double cd = 12.54; int main() { double md = M; double dcd = cd; double md1 = M; double dcd1 = cd; return 0; }
- 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。既然这么好,能使用const就使用const。
二、const+数据类型+变量。
const int ci = 2;//定义初始化
ci = 3; //error:ci是const,不能变
const double* pd = &dcd; // 和double const* pd = &dcd;一样
pd = &md;
*pd = M; //Error:指针指向内容const不能变
double* const p = &dcd;
*p = M;
p = &cd; //Error:指针是const
const double* const pcc = &dcd; //指针和内容都是const
pcc = &cd;
*pcc = M;
三、普通const函数
a.传递过来的参数在函数内不可以改变(无意义,因为Var本身就是形参)
void function(const int Var);
b.参数指针所指内容为常量不可变
void function(const char* Var);
c.参数指针本身为常量不可变(也无意义,因为char* Var也是形参)
void function(char* const Var);
d.参数为引用,为了增加效率同时防止修改。修饰引用参数时:
void function(const Class& Var); //引用参数在函数内不可以改变
void function(const TYPE& Var); //引用参数在函数内为常量不可变
不建议const作为函数返回值
四、类的成员函数和成员变量
class test {
public:
test(int _a) :a(_a), b(0.12),c(0)/*必须初始化*/{
pb = new int[10];
}
//const成员函数,把const放在函数声明的末尾就可以了,表示该函数无法改变类的数据成员
//只能发生读操作,不能发生写操作
void init_variable()const
{
//a = 5;//不可以改变数据成员的值
std::cout << a << std::endl;
pb[0] = 10;//不能修改指针,但修改指针指向的内容是可以的。
std::cout << pb[0] << std::endl;
c++; //mutable
}
void init_variable()
{
//a = 5;//不可以改变数据成员的值
//b = 3.2;//const数据成员变量不能改变
std::cout << a << std::endl;
std::cout << pb[0] << std::endl;
}
~test()
{
delete pb;
pb = NULL;
}
private:
int a;
int* pb;
const double b;
mutable int c;//关键字mutable使得c在const成员函数中也可以改变。
};
int main()
{
const test mytest(4);
mytest.init_variable();//可以调用const成员函数
test test1(6);
test1.init_variable();
return 0;
}
五、static和const(
static理解)
这个看这篇文档就知道了const_static
好了,写到这里我也对const有了比较深的理解,不知道大家感觉如何。尽量用const。