c++ primer(第五版)笔记 第二章(4)const, decltype, auto

来源:互联网 发布:javascript运算符 编辑:程序博客网 时间:2024/06/05 20:32
#ifndef LESSON_2_4_H#define LESSON_2_4_H#include <iostream>extern const int ciExt;inline void print_ciExt(){std::cout << ciExt << std::endl;}#endif // !LESSON_2_4_H

#include "lesson_2_4.h"#include<typeinfo>extern const int ciExt = 4;void auto_test();void practice_2_26();void practice_2_27();void practice_2_28();void practice_2_29();void const_test();void constexpr_test();void alias_test();void decltype_test();struct Foo{};//注意分号int main(){//通过 const 关键字将变量定义成一个常量,而且以后不能再改变,所以 const 对象必须初始化,只能进行不改变其内容的操作//const 对象默认仅在文件内有效,如果需要多文件共享,需要在声明和定义时,使用 extern 关键字(在函数中进行该操作会报错)print_ciExt();//4头文件中 ciExt 和本文件中的 ciExt 是同一个对象practice_2_26();practice_2_27();practice_2_28();practice_2_29();const_test();constexpr_test();alias_test();auto_test();decltype_test();return 0;}void practice_2_26(){//const int buf;//Errorconst object must be initialized if not externint cnt = 0;const int sz = cnt;++cnt;//++sz;//Errorcannot assign to a variable that is const}void practice_2_27(){//int i = -1, &r = 0;//'initializing' : cannot convert from 'int' to 'int &'const int i = -1, &r = 0;const int i2 = i;const int *p1 = &i2;//int *const p2 = &i2;//'initializing' : cannot convert from 'const int*' to 'int *const'const int *const p3 = &i2;}void practice_2_28(){//int i, *const cp; i整型,cp 指向int的 const 指针,必须初始化//int *p1, *const p2; p1 整型指针,p2 指向int的 const 指针,必须初始化//const int ic, &r = ic; ic 常量,必须初始化, r 绑定整型常量 ic//const int *const p3; p3 是一个指向整型常量的常量指针,必须初始化const int *p; //p指向整型常量}void practice_2_29(){//i = ic; const int 不能转换为 int//p1 = p3; const int* const 不能转换为 int *//p1 = &ic; const int* 不能赋值给 int *//p3 = &ic; p3是个常量,不能改变值//p2 = p1; p2是个常量,不能改变值//ic = *p3; ic是个常量,不能改变值}void const_test(){//const 的引用(reference to const)//引用类型和所引用对象的类型不一致的特例之一://在初始化常量引用时,允许用任意表达式作为初始值,只要能转换成引用的类型即可,比如非常量的对象,字面值,表达式double dval = 3.14;const int &ri = dval;//要保证 ri 所能执行的整数运算,上述代码通过编译器变为//double dval = 3.14;//const int temp = dval;//const int &ri = temp;//如果 ri 不是一个 const, 则通过 ri 应该可以改变所引用的对象 dval,但实际上 ri 绑定到一个临时量对象上,这种引用显然是无意义的,c++ 就把这种行为归为非法//指向常量的指针(pointer to const)//指针类型和所指向对象的类型不一致的特例之一://允许令一个指向常量的指针指向一个非常量对象//所谓的指向常量的指针和引用,不过是指针和引用觉得自己指向常量,自觉不去改变,但所指向的对象可以通过其他途径改变值//执行对象拷贝时,顶层 const 不受影响,但必须有相同的底层 const 资格const int v2 = 0;int v1 = v2, *p1 = &v1, &r1 = v1;const int *p2 = &v2, *const p3 = &v2, &r2 = v2;r1 = v2;//v2的顶层 const 被忽略//p1 = p2;//p2 具有底层 const, p1不具备p2 = p1;//p1 = p3; p3 的顶层 const 被忽略,但p1 不具备底层 const p2 = p3;//p3 的顶层 const 被忽略,并且和 p2 具备底层 const }void constexpr_test(){//常量表达式(const expression),值不会改变并且在编译过程就能得到计算结果的表达式//c++11 规定,允许将变量声明为 constexpr 类型以便由编译器来检验变量的值是否是一个常量表达式//字面值类型(literal type),算术类型,指针,引用//constexpr 的指针初始值必须为 nullptr 或者 0 或者存储在固定地址(定义于函数体外的对象)中的对象//constexpr 限定符仅对指针有效,对指向对象无关constexpr int *p = nullptr;//指向整数的常量指针constexpr const int *p = nullptr;//指向整数常量的常量指针}void alias_test(){using pstring = char*;//c++11typedef char * pstring1;//pstring类型相同const pstring cstr = 0;//指向 char 的常量指针const pstring1 *ps = 0;//指针,指向一个指向char的常量指针}void auto_test(){//c++11 引入 auto 类型说明符,让编译器去分析表达式类型//定义 auto 引用时,顶层 const 保留,其他类型只保留底层 const//2.35const int i = 42;std::cout << "type" << " i " << typeid(i).name() << std::endl;auto j = i;//intstd::cout << "type" << " j " << typeid(i).name() << std::endl;const auto &k = i;//const int&std::cout << "type" << " i " << typeid(k).name() << std::endl;auto *p = &i;//const int*std::cout << "type" << " i " << typeid(p).name() << std::endl;const auto j2 = i; //const intstd::cout << "type" << " i " << typeid(j2).name() << std::endl;const auto &k2 = i;//const int std::cout << "type" << " i " << typeid(k2).name() << std::endl;}void decltype_test(){//decltype返回变量和表达式的类型,包括 const 和 引用const int i = 0, &r = i;decltype(i) x = 0;//x const intdecltype(r) y = 0;//y const int&//decltype(r) z;//z const int& 必须初始化//如果表达式是一个解引用操作,decltype 返回引用类型int j = 0, *p = &j, &r1 = j;decltype(r1 + 0) h;//a int,r1 + 0的结果是 int//decltype(*p) k;//b int& 必须初始化//如果为变量增加一层括号,将得到引用decltype(j) l;//c intdecltype((j)) m = j ;// int &,必须初始化//2.36int a = 3, b = 4;decltype(a) c = a;//c intdecltype((b)) d = a;//d int&, (b) 不被视为变量,而是一个表达式++c;//a = 3, b = 4, c = 4, d = 3std::cout << a << b << c << d << std::endl;++d;//a = 4, b = 4, c = 4, d = 4std:: cout << a << b << c << d << std::endl;//2.37//赋值是一类产生引用的表达式,其引用的类型为左值的类型decltype(a = b) e = a;//e int &}

0 0
原创粉丝点击