作为大四应届生o( ̄︶ ̄)o 最近为了后续的面试工作地点看C++primer再次深入学习C++写里一点笔记:
如下:
1. io库
• **istream(输入流)类提供输入操作。
• ostream(输出流)类提供输出操作。
• cin,一个istream对象,从标准输入读取数据。
• Cout,一个ostream对象,向标准输出写入数据。
• cerr.一个。stream对象,通常川J几输出程序错误消臼、,写入到标滩错误
• >>运算符,用来从一个istream对象读取输入数据
• <<运算符,少目来向一个ostream对象写入输出数据
• getline函数从一个给顶的istream读取行数据 存入一个给定的string对象。**
2.C++刷新机制:
一下几种情况会导致缓冲区内容被刷新,即写入到真实的输出设备或者文件:
1. 程序正常结束, 作为main 返回工作的一部分,将情况所有输出缓冲区;
2. 一些不确定的时候,缓冲区可能已满;
3. 使用manipulator 显示属性缓冲区, 比较常用的是endl, flush, ends:
cout<<"hi"<
cout<<"hi"<
cout<<"hi"<
4. 使用unitbuf 设置流的内部状态, 适合所有输出都要刷新缓冲区,unitbuf 和nounitbuf 之间的区域每次写完后都刷新流
cout<
等价于
cout<<"first"<
5. 使用tie 将输入流和输出流关联起来, 这种情况下,在读输入流时将刷新其关联的输出缓冲区,标准库默认将cout 和cin 绑在一起;
cin.tie(&cout); // cin 和cout 关联
cin.tie(0); // 解除该流上已存在的捆绑
3.C++ 左右值
左值、右值
在C++11中所有的值必属于左值、右值两者之一,右值又可以细分为纯右值、将亡值。在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。举个例子,int a = b+c, a 就是左值,其有变量名为a,通过&a可以获取该变量的地址;表达式b+c、函数int func()的返回值是右值,在其被赋值给某一变量前,我们不能通过变量名找到它,&(b+c)这样的操作则不会通过编译。
右值、将亡值
在理解C++11的右值前,先看看C++98中右值的概念:C++98中右值是纯右值,纯右值指的是临时变量值、不跟对象关联的字面量值。临时变量指的是非引用返回的函数返回值、表达式等,例如函数int func()的返回值,表达式a+b;不跟对象关联的字面量值,例如true,2,”C”等。
C++11对C++98中的右值进行了扩充。在C++11中右值又分为纯右值(prvalue,Pure Rvalue)和将亡值(xvalue,eXpiring Value)。其中纯右值的概念等同于我们在C++98标准中右值的概念,指的是临时变量和不跟对象关联的字面量值;将亡值则是C++11新增的跟右值引用相关的表达式,这样表达式通常是将要被移动的对象(移为他用),比如返回右值引用T&&的函数返回值、std::move的返回值,或者转换为T&&的类型转换函数的返回值。
将亡值可以理解为通过“盗取”其他变量内存空间的方式获取到的值。在确保其他变量不再被使用、或即将被销毁时,通过“盗取”的方式可以避免内存空间的释放和分配,能够延长变量值的生命期。
左值引用、右值引用
左值引用就是对一个左值进行引用的类型。右值引用就是对一个右值进行引用的类型,事实上,由于右值通常不具有名字,我们也只能通过引用的方式找到它的存在。
右值引用和左值引用都是属于引用类型。无论是声明一个左值引用还是右值引用,都必须立即进行初始化。而其原因可以理解为是引用类型本身自己并不拥有所绑定对象的内存,只是该对象的一个别名。左值引用是具名变量值的别名,而右值引用则是不具名(匿名)变量的别名。
左值引用通常也不能绑定到右值,但常量左值引用是个“万能”的引用类型。它可以接受非常量左值、常量左值、右值对其进行初始化。不过常量左值所引用的右值在它的“余生”中只能是只读的。相对地,非常量左值只能接受非常量左值对其进行初始化。
int &a = 2; # 左值引用绑定到右值,编译失败
int b = 2; # 非常量左值
const int &c = b; # 常量左值引用绑定到非常量左值,编译通过
const int d = 2; # 常量左值
const int &e = c; # 常量左值引用绑定到常量左值,编译通过
const int &b =2; # 常量左值引用绑定到右值,编程通过
右值值引用通常不能绑定到任何的左值,要想绑定一个左值到右值引用,通常需要std::move()将左值强制转换为右值,例如:
int a;
int &&r1 = c; # 编译失败
int &&r2 = std::move(a); # 编译通过
下表列出了在C++11中各种引用类型可以引用的值的类型。值得注意的是,只要能够绑定右值的引用类型,都能够延长右值的生命期。
4 C++引用类型转换
这里std::move的作用是强制一个左值成为右值(看起来很奇怪?这个我们会在下面一节中解释)。该函数就是使用右值来初始化Copyable变量news。当然,如同我们在上小节提到的,使用移动语义的前提是Copyable还需要添加一个以右值引用为参数的移动构造函数,比如:
Copyable(Copyable &&o) { /* 实现移动语义 */ }
来自https://book.2cto.com/201306/25366.html
5.C++11 lambda
简介
Lambda 可能是最新的 C++11 标准的典型特性之一。Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。
清单 2
Lambda 表达式的基本语法
Lambda 表达式本质上与函数声明非常类似。我们可以提取清单 2 中的 lambda 表达式,详加说明。提取的 lambda 表达式如清单 3 所示:
[](int x, int y){ return x < y ; }
清单 3
如果我们将 lambda 表达式比作函数,可以看到它与函数名对应的是一对空的方括号,即捕获表达式。这些括号表示后面跟着一个 lambda 表达式。这些方括号不必为空;稍后将讨论其内容。
如果 lambda 主体只含一个返回类型,则暗示返回的表达式类型为 lambda 返回类型。如果要显式指定返回类型,需使用新的 C++11 语法表示函数声明中的后置返回类型。对于返回类型 T 的普通函数,您可以这样编写:
auto foo(…) -> T { … }
对于 lambda,您需要要这样编写:
[] (…) -> T { … }
lambda 表达式的其余部分与常规 C 或 C++ 函数主体类似。
将 Lambda 传递到函数指针
C++11 标准库中有一个名为 function 的模板,它可以接受指定类型的函数或者具有匹配的返回类型和参数列表的 lambda。这将产生一个指向函数类型的指针,例如,清单 4 可用作函数参数类型,接受 int 参数,返回 void。您可以向其传递任何类似匹配函数或 lambda 的内容。
std::function