C++中的const继承于C中的关键字const,但是在底层实现上已经有了本质的区别。
在C语言中,被const修饰过的关键字只能称之为常变量,或者说是一个只读的变量,它本身仍然可以通过一些手段来进行修改,如指针。
下面是一段C的代码:
#include <stdio.h>
int main()
{
const int i = 10;
printf("i = %d\n", i);
int*p = &i;
*p = 20;
printf("i = %d\n", i);
return 0;
}
这是这段代码编译后的警告以及运行后的结果,但事实证明,C中的const修饰过的变量的确可以被修改。
但是在C++中,被const关键字修饰过的关键字就已经是一个常量了。在底层的实现方式上类似于key-value一样的结构,通过符号表的形式来进行实现,类似C中的#define
,会在编译期间进行替换。
但是C++中的const更加严格,因为它除了定义为一个常量,还有类型检查,所以比#define
更加严格。
同样的代码,我们用C++编译器g++来进行编译,得到的结果如下:
因此我们可以得知,这是从编译层面做了根本的修改。
不过替换这种方式在C++中只是对内置类型进行替换,像struct、class这种自定义类型,C++不知该如何替换,故而仍然要在内存中进行读取,因此,内置类型的const处理方式与自定义类型不同。
struct test{
int var;
test()
{
var = 1;
}
};
int main()
{
using namespace std;
const test t;
cout<< t.var << endl;
int* p = (int*)(&t.var);
*p = 30;
cout << t.var << endl;
return 0;
}
打印出来的运行结果是1和30。 因此,非内置类型的处理其实和C语言的处理方式还是很相似的,因为还要在内存中读取这个数据,因此直接通过指针来对内存修改仍然会改变非内置类型的数据。
但我们仍然要好好利用const这个关键字,因为这会给我们所写的代码带来很多的便利,比如函数参数的类型检测,作用域的不同,类型的不同,都可以通过const来加以限制。