C++和C比较之:C++中const的权限更加严苛(对于普通变量)

    传统认为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要严格,实现了数据权限管理,这样为面向对象也做好了准备。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章