传统认为C++是C的超集,所以C++会在C的基础上进行补充和规范。下面我们对C++中函数变量const权限的问题进行对比,主要对比的是用const修饰的基础变量(非类和指针,引用,对象)。对比的范围是const修饰全局变量和局部变量。
我们知道无论是C还是C++中的变量用const修饰,那就意味着这个变量一旦初始化就不能在被修改。比如:
一. 无论在C还是C++中下面的程序都是错误的:
#include<stdio.h>
const int global = 20;
int main()
{
const int local =10;
local = 100; // 错误的,不可以修改
global = 200; // 错误的,不可以修改
printf("global is %d, local is %d\n", global, local);
return 0;
}
因为global 和local都是const变量,从语义上可以知道这两个变量是不可更改的,因此如果修改话是不允许的。这一点两者是一致的。
二. const修饰全局变量。我们知道不论C还是C++,程序中const变量位于内存中RO段内,所以很明显,如果修改这些变量会出现Segmentation fault (core dumped)的错误。如下:是C的文件:
//const.c
#include<stdio.h>
const int a = 10;
const int global = 100;
int g_var_init = 200;
int g_var_N_init;
int main()
{
int b = 20;
int c = 30;
printf("&a:%p, &b:%p, &c:%p\n", &a, &b, &c);
printf("a:%d, b:%d, c:%d\n", a, b, c);
int *d = (int *) &a;
*d = 40;
printf("&a:%p, &b:%p, &c:%p, d->:%p\n", &a, &b, &c, d);
printf("a:%d, b:%d, c:%d, d:%d\n", a, b, c, *d);
return 0;
}
编译以后:gcc -g -o const testConst.c -Wall,我们用nm查看:
可以看到全局变量const a被分配到了RO区域,执行以下生成的binary文件:
出现了Segmentation fault (core dumped)的错误。
对于C++程序来说:
//const.cpp
#include<stdio.h>
const int a = 10;
const int global = 100;
int main()
{
int b = 20;
int c = 30;
printf("&a:%p, &b:%p, &c:%p\n", &a, &b, &c);
printf("a:%d, b:%d, c:%d\n", a, b, c);
int *d = (int *) &a;
*d = 40;
printf("&a:%p, &b:%p, &c:%p, d->:%p\n", &a, &b, &c, d);
printf("a:%d, b:%d, c:%d, d:%d\n", a, b, c, *d);
return 0;
}
编译后:g++ -g -o constCpp testConst.cpp -Wall
nm一下:
运行:
可以看到和C语言的结果一样。
三. const 修饰函数变量,此时变量都会在RAM的数据区,对于C语言来说对const变量强制进行转化后可以修改const的值,而C++不可以,下面看代码:
C代码:
//const.c
#include<stdio.h>
int main()
{
const int a = 10;
int b = 20;
int c = 30;
printf("&a:%p, &b:%p, &c:%p\n", &a, &b, &c);
printf("a:%d, b:%d, c:%d\n", a, b, c);
int *d = (int *) &a;
*d = 40; // a的值被修改了
printf("&a:%p, &b:%p, &c:%p, d->:%p\n", &a, &b, &c, d);
printf("a:%d, b:%d, c:%d, d:%d\n", a, b, c, *d);
return 0;
}
编译并运行:
可以看到const修饰的变量已经修改。
对于C++的情况:
//const.cpp
#include<stdio.h>
int main()
{
const int a = 10;
int b = 20;
int c = 30;
printf("&a:%p, &b:%p, &c:%p\n", &a, &b, &c);
printf("a:%d, b:%d, c:%d\n", a, b, c);
int *d = (int *) &a;
*d = 40;
printf("&a:%p, &b:%p, &c:%p, d->:%p\n", &a, &b, &c, d);
printf("a:%d, b:%d, c:%d, d:%d\n", a, b, c, *d);
return 0;
}
编译运行:
可以看到a的值没有发生变化,想知道为什么小伙伴可以分析g++生成的汇编去查询。
结论:
由此可以看出,C++对const的管理比C要严格,实现了数据权限管理,这样为面向对象也做好了准备。