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要嚴格,實現了數據權限管理,這樣爲面向對象也做好了準備。

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