C++ Primer

xiaoxiao2021-02-28  36

1,const限定符

const对变量的类型加以限定,必须初始化,不允许更改。

const对象默认仅在文件内有效,若要在多个文件内使用,需要用extern加以限定(不管是声明还是定义):

//file_1.cc定义并初始化了一个常量,该常量能被其他文件访问 extern const int bufSize = fcn(); //flie_1.h头文件 extern const int bufSize;// 与file_1.cc中定义的bufSize是同一个

const和引用

可以把引用绑定到const对象上,但必须对引用也用const加以限定:

const int ci = 1024; const int &r1 = ci;//引用及其对应的对象都是常量

初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可:

int i = 42; const int &r1 = i;        //正确:允许讲常量引用绑定到普通变量对象上 const int &r2 = 42;       //正确:r1是一个常量引用,允许字面值作为初始值 const int &r3 = r1*2;     //正确:r3是一个常量引用,允许用表达式作为初始值 int &r4 = r1*2;           //错误:r4是一个普通的非常量引用

当一个常量引用被绑定到另外一个类型上会发生什么:

double dval = 3.14; const int &ri = davl;

int型的ri却绑定了一个double类型,为了确保让ri绑定一个整数,编译器将上述代码作了改变:

const int temp = dval; //由双精度浮点数生成一个临时的整形常量 const int &ri = temp; //让ri绑定这个临时量

当const引用绑定到一个非const对象时,

常量引用不允许通过自身修改值,但是可以通过引用的对象本身,或其他非常量引用来改变:

int i = 42; int &r1 = i; const int &r2 = i; i=0;                 //正确:i非常量,此时i,r1,r2均被改为0 r1=1;                //正确:r1非常量引用,此时i,r1,r2均被改为1 r2=2;                //错误:r2是一个常量引用,不允许自身修改

指向常量的指针(底层const)

const修饰的指针不能用于改变其所指对象的值。

想要存放常量对象的地址,只用使用指向常量的指针。

和常量引用一样,指向常量的指针也没有规定所指向的对象必须是一个常量。

(指针自认为自己指向了常量,故不能通过指针去改变所指对象的值)

double dval = 3.14;            //dval是一个双精度副点数,它的值可以边改 const double *cptr = &dval;    //正确:但是不能通过cptr改变dval的值

const指针/常量指针(顶层const)

允许把指针本身定为常量,称为常量指针。必须初始化,初始化完成,它的值(存放在指针中的地址)就不能改变了。

int ri = 0; int *const p1 = &ri; //p1将一直指向ri const double pi = 3.14159; const double *const p2 = π //p2是一个指向常量对象的常量指针常量指针本身值不能改变,但是如果指向非常量,则完全可以通过常量指针去修改指向对象的值。 *p1 = 3.14;      //正确:p1是指向非常量的常量指针,可以通过指针改变 *p2 = 3.14;      //错误:p2是指向常量的常量指针,不可以通过指针改变

顶层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的值,这是一个底层const const int *const p3 = p2; //靠右的const是顶层const,靠左的是底层const const int &r = ci; //用于声明引用的const都是底层const    

当执行对象的拷贝操作时,常量是顶层const还是底层const区别明显。其中,顶层const不受什么影响:

i = ci;                     //正确:ci是一个顶层const,拷贝无影响 p2 = p3;                      //正确:p2、p3都是底层const,但指向的对象类型相同,p3顶层const的部分不影响 int *p = p3;                  //错误:p3包含底层const,但p没有 p2 = &i;                      //正确:int*能转换成为 const int* int &r = ci;                  //错误:普通的int& 不能绑定到int常量上 const int &r2 = i;            //正确:const int&可以绑定到一个普通int上

constexpr和常量表达式.

常量表示式是指值不会改变并且在编译过程就能 得到计算结果的表达式。

const int max_files = 20;            // max_files是常量表达式 const int limit = max_flies+1;       //limit是常量表达式 int staff_size =27;                  //staff_size不是(数据类型不是常量)const int sz = get_size();           //sz不是常量表达式(运行后才能得到值)

constexpr变量(C++11新特性)

将声明为constexpr类型的变量由编译器 来验证变量是否是一个常量表达式,该变量一定是常量,且不需用常量表达式初始化。

constexpr int mf = 20;                //20是常量表达式 constexpr int limit = mf+1;           //mf+1是常量表达式 constexpt int sz = size();          //只有当size是一个constexpr函数时,才是一条正确的声明语句

指针和constexpr

constexpr指针的初始值必须是nullptr或者0,或者是存储于某个固定地址中的对象。

定义于所有函数之外的对象其地址固定不变,能用来初始化constexpr指针。

在constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效,与指针所指的对象无关:

const int *p =nullptr;        //p是一个指向整数常量的指针 constexpr int *q = nullptr;    //q是一个指向整除的常量指针

constexpr把它所定义的对象置为了顶层const。

与其他常量指针类型,constexpr指针既可以指向常量也可以指向一个非常量:

constexpr int *np =nullptr;        //np是一个指向整数的常量指针,其值为空 int j = 0; constexpr int i =42;               //i的类型是正常常量 //i和j都必须在函数体外 constexpr const int *p =&i;        //p是常量指针,指向整形常量i constexpr int *p1 = &j             //q是常量指针,指向整数j

转载请注明原文地址: https://www.6miu.com/read-2650148.html

最新回复(0)