c++const限定符总结

const关键字介绍

const关键字作用的本质就是保证变量的值不改变而设计的。那什么是所谓的变量值不变呢?首先要知道变量两个组成部分一个是变量名,一个是存储空间;
注意事项:const修饰的变量必须在定义的时候初始化;const修饰的变量默认有效范围在单个文件内有效,如果要设置多个文件共享const对象,必须在变量定义之前加extern关键词;const修饰位置也是有讲究的,见第二个程序;

const int a = 1000;
a=200;  //错误,试图改变变量的值
//多个文件共享const对象
//file1.h
extern const int buffersize;  //只声明
//file2.cc
extern const int buffersize = 1024; //初始化常量(定义)

const修饰位置规则:如果修饰变量名(门牌号),就说明变量(门牌号)无法修改;如果const修饰变量的内存空间(例如 consst int),说明变量的内存空间无法修改。
const int a; 与 int const a;//是等价的,这是因为int a;变量a只能通过a才能对其内存空间赋值;
const int & a; 与 int const & a; //也是等价的,引用就是变量的别名
const int * a;  //指向常量整数的指针,很明显const修饰是变量的内存空间,因此指针a指向的内存空间无法被修改;
//例如
*a=100; // 错误
int b = 200;
a = &b; //正确
int * const a; //常量的整型指针,由于const修饰变量名本身,说明变量名无法修改,无法将指针指向另一块内存空间
//例如
*a = 100; //正确
int b = 300;
a = &b; //错误

const引用

const引用就是用const关键修饰引用变量,而引用本身就是绑定对象本身,在我看来,可以理解为const int & a 等价于绑定的对象加上了const

const引用和普通引用的区别:
const引用类型可以与其引用对象不一致(但会出问题,详细见下面程序);
const引用可以绑定非常量(const)对象、字面值甚至表达式;
普通引用无法绑定常量(const)对象。

    cout << "常量引用与普通引用对比" << endl;
    int i = 42;
    const int j = 2;
    const int &r1 = i;
    const int &r2 = 42;
    const int &r3 = r1*2;
    //int &r4 = j; //错误,普通引用无法绑定常量对象(如果可以绑定的话,const就失去意义了)

    cout << "常量引用类型与其绑定对象不一致对比" << endl;
    int a = 100;
    const int  &b = a; //这时候常量引用b是无法赋值的
    a = 300;
    cout << "a=" << a << " b=" << b  << endl; //输出结果:a=300 b=300 解释:如果类型
    //一致,常量引用b绑定的对象是变量a,因此两者都发生了改变

    double deval = 3.14;
    const int  & d = deval;
    deval = 2.14;
    cout << "deval=" << deval << " d=" << d << endl; //输出结果:deval=2.14 d=3
    //解释:常量引用在绑定对象时候c++会发生类型转换,相当于执行以下代码:
    // const int temp = deval
    // oonst int &d = temp;
    //因此,这时常量引用b绑定的是临时对象,这样一来,使用引用的意义就没有了

const指针

const指针,无论const修饰变量名还是变量内存空间,const指针和要指向的地址空间类型要一致;普通指针无法指向常量类型。

顶层const

指针本身是一个对象,并且指针指向也是一个对象,因此指针本身是不是常量以及指针指向的是不是一个常量是两个独立的问题。顶层const表示指针本身是常量,底层const表示指针指向的对象是一个常量。更一般的,顶层const表示可以任意对象(算术类型,类,指针)是常量,底层const表示指向的对象或者引用的对象是常量,根据底层const特点在c++中只有指针对象和const引用具有底层const,其中指针对象的顶层const通常是const修饰在变量前,而底层const通常修饰在类型名称前。
顶层const无法修改变量的值,底层const无法改变变量指向的值。
当执行对象拷贝时候,拷入对象和烤出对象必须具有相同的底层const或者两个对象能够转换,通常情况下,非常量可以转成常量,反之则不行。

int  i = 0;
int * const p1 = &i;  //不能改变p1的值,这是顶层const
const int ci = 42;    //不能改变ci的值,这是个顶层const
const int *p2 = &ci; //允许改变p2的值,但不允许改变p2指向整形的值,这是个底层const
const int * const p3 = p2;  //既不能改变p3的值,也不能改变p3指向的指针,这是顶层const又是个底层const
const int &r = ci; //用于声明引用的const都是底层const
//对象拷贝
int *p = p3;  //错误:p3具有底层const而,p指针没有
p2 = p3; //正确:p2和p3都具有底层const
p2 = &i; // 正确:p2具有底层const,但非常量可以转换为常量
int &r = ci; //错误:普通int引用不能与常量int绑定
const int &r2 = i; //正确,常量int引用可以绑定普通int

你可能感兴趣的:(c++const限定符总结)