博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++11的新特性
阅读量:3943 次
发布时间:2019-05-24

本文共 6156 字,大约阅读时间需要 20 分钟。

文章目录

c++ 新特性

auto关键字

auto 能做什么

//编译器能通过上下文,推断出auto变量的类型auto fun(int a,int b){
return a + b;}int main(){
auto a = 10; auto c = 'c'; auto str = "qwe"; return 0;}

在c++ 14中auto 可以作为函数的返回值;

auto可以用于定义函数,不能用于声明函数,例如:

class Test{
public: //会发生变异时的错误 auto TestWork(int a ,int b);};

nullptr用法

class Test{
public: Test(int index) {
cout << "Test(int)" << endl; } Test(void *ptr) {
cout << "Test(void *ptr)" << endl; }};int main(){
Test(NULL); //NULL 是宏定义,代表整形值0 Test(nullptr);}

在这里插入图片描述

for循环

int main(){
vector
vec; for(int i = 0; i < 10; i++) {
vec.push_back(rand()); } //内部迭代器实现 for(auto val:vec) {
cout << val << " "; } cout << endl; return 0;}

STL

数组array

int main(){
//用法与普通的数组基本一样, //在底层封装了迭代器 array
arr = {
1,2,3,4}; for(auto val:arr) {
cout << val << " "; } cout << endl; int size = sizeof(arr); cout << "数组的字节数" << size << endl;}

forward_list

与list 一样都是链式结构,list 采用的是双向链表,forward_list 采用的是单向链表

int main(){
//用法与list 的用法一样 forward_list
ls; for(int i = 0; i < 10; i++) {
ls.push_front(rand()); } for(auto val:ls) {
cout << val << " "; } cout <

unordered_map 与 unordered_set

使用方法与map 类似,只是底层实现的数据结构不一样,map set 基于红黑树

unordered_map 与unordered_set底层实现的数据结构是哈希表,所以在选择容器的时候,如果对数据的有序性有要求,则选择map 或则 set ;如果对有序性没有要求,则选择unordered_map 或者 ubordered_set,因为哈希表的增删查的时间复杂度都接近于O(1

int main(){
srand(time(0)); unordered_map
ma; for(int i = 0; i < 100; i++) {
ma[rand() % 10 + 1]++; } for(auto val:ma) {
cout << val.first << "==>" << val.second << endl; } return 0;}

多线程

thread

void threadfun1(){
cout << "threadfun1()" << endl; this_thread::sleep_for(chrono::seconds(1)); cout << "threadfun1() over" << endl;}void threadfun2(int a,string str){
cout << a << " == >" << str << endl; cout << "threadfun2()" << endl; this_thread::sleep_for(chrono::seconds(5)); cout << "threadfun2() over" << endl;}int main(){
//线程执行threadfun1函数 thread t1(threadfun1); //线程执行threadfun2函数 thread t2(threadfun2,10,"abc"); //主线程等待线程的结束 t1.join(); cout << "t1.join()" << endl; //不等待现成的结束。 t2.detach(); cout << "t2.detach()" << endl; return 0;}

atomic

atomic 为c++11 封装了原子数据类型。

从功能上看,简单地说,原子数据类型不会发生数据竞争,能直接用在多线程中而不必我们用户对其进行添加互斥资源锁的类型。从实现上,大家可以理解为这些原子类型内部自己加了锁。

atomic_int iCount;void threadfun(){
for(int i = 0; i < 10000; i++) {
iCount++; }}int main(){
vector
vec; for(int i = 0; i < 10; i++) {
vec.push_back(thread(threadfun)); } for(auto &val:vec) {
val.join(); }}

在这里插入图片描述

condition_variable

C++11中的std::condition_variable就像Linux下使用pthread_cond_wait和pthread_cond_signal一样,可以让线程休眠,直到被唤醒,再从新执行。线程等待在多线程编程中使用非常频繁,经常需要等待一些异步执行的条件的返回结果。

mutex mu;condition_variable cv;bool ready = false;void threadfun(int id){
cout << id << "已经到达" << endl; while(!ready) {
unique_lock
lck(mu); //阻塞线程直到ready为true为止 cv.wait(lck); }}void go(){
unique_lock
lck(mu); ready = true; //唤醒所以线程 cv.notify_all();}int main(){
vector
vec; for(int i = 0; i < 10; ++i) {
vec.push_back(thread(threadfun,i)); } cout << "all threads ready" << endl; go(); for(auto &val:vec) {
val.join(); } return 0;}

智能指针

shared_ptr

带引用计数的的智能指针,也叫强引用指针

class Test{
public: Test() {
cout << "Test()" << endl; } ~Test() {
cout << "~Test()" << endl; }private: int *ptr;};int main(){
shared_ptr
t1(new Test); //智能指针的拷贝构造时,不重新申请内存,不调用构造函数 //只是将第一次开辟的内存的引用计数加一 shared_ptr
t2(t1); //输出2 cout << t1.use_count() << endl; //输出2 cout << t2.use_count() << endl; return 0;}

weak_ptr

带引用计数的智能指针,弱引用计数

class Test{
public: Test() {
cout << "Test()" << endl; } ~Test() {
cout << "~Test()" << endl; }private: int *ptr;};int main(){
shared_ptr
t1(new Test); //智能指针的拷贝构造时,不重新申请内存,不调用构造函数 //内存的引用计数不变,强引用指针的观察者数量加一 weak_ptr
t2(t1); //输出1 cout << t1.use_count() << endl; //输出1 cout << t2.use_count() << endl; return 0;}

循环引用问题

class B;class A{
public: A() {
cout << "A()" << endl; } ~A() {
cout << "~A()" << endl; } shared_ptr ptr_b;};class B{
public: B() {
cout << "B()" << endl; } ~B() {
cout << "~B()" << endl; } shared_ptr ptr_a;};int main(){
shared_ptr
ptra(new A); shared_ptr ptrb(new B); ptra->ptr_b = ptrb; ptrb->ptr_a = ptra; cout << ptra.use_count() << endl; cout << ptrb.use_count() << endl;}

在这里插入图片描述

可以看到结果中调用了A B 的构造函数,但是并没有调用析构函数,说明存在内存的泄漏。产生的 原因是:

shared_ptr ptra(new A);	shared_ptr ptrb(new B);

两句分别使ptra 和 ptrb 指向了新开辟的两块内存,此时两块内存的引用计数都为1,

当执行

ptra->ptr_b = ptrb;	ptrb->ptr_a = ptra;

的时候,两块内存的引用计数都分别加一,两块内存的引用计数都变为2,

当程序结束的时候,ptra 指针析构,内存A的引用计数变为1,不释放内存,ptrb 指针析构,内存B 的引用计数变为1,不释放内存。所以,再程序结束的时候,两块内存的引用计数并没有变为0.
解决方法:

class B;class A{
public: A() {
cout << "A()" << endl; } ~A() {
cout << "~A()" << endl; } shared_ptr ptr_b;};class B{
public: B() {
cout << "B()" << endl; } ~B() {
cout << "~B()" << endl; } weak_ptr ptr_a;};int main(){
shared_ptr
ptra(new A); shared_ptr ptrb(new B); ptra->ptr_b = ptrb; ptrb->ptr_a = ptra; cout << ptra.use_count() << endl; cout << ptrb.use_count() << endl;}

在这里插入图片描述

bind

#include 
#include
using namespace std;/* bind 函数的使用*/class comp{
public: bool operator()(int a,int b) {
return a > b; }private:};bool func(int a,int b){
return a > b;}int main(){
//将f指向绑定后的函数函数 //
表示形参列表,返回值类型 //绑定后的结果可以通过std::function进行保存 //bind参数 函数指针,函数的参数列表 function
f = bind(comp(), 1, std::placeholders::_1); //std::placeholders::_2 表示占位符,表示实参的第二个放到该位置, cout << bind(func, std::placeholders::_2, 1)(2,-1) << endl; //调用绑定后的函数 cout << f(-1) << endl; return 0;}

function

//如果一个函数的要求既能接受函数指针,也能接受函数对象class Test{
public: //function 可以结合bind 使用,对bind 的函数进行保存 //也可以作为形参,不仅可以接受函数指针,还可以接受函数对象 int Add(function
f,int a,int b) {
return f(a,b); }};int main(){
//类似于函数指针的用法 void func(int); funtion
f = func; return 0;}

lambda 表达式

lambda的声明方式

[capture list] (params list) mutable exception-> return type {
function body }各项具体含义如下1、capture list:捕获外部变量列表2、params list:形参列表3、mutable指示符:用来说用是否可以修改捕获的变量4、exception:异常设定5、return type:返回类型6、function body:函数体

此外还有几种简写的方式

在这里插入图片描述
capture list:捕获外部变量列表
在这里插入图片描述

转载地址:http://zxnwi.baihongyu.com/

你可能感兴趣的文章
各大浏览器兼容性报告
查看>>
统计每个ip的访问量--linux--acces…
查看>>
常见hash算法的原理
查看>>
localForage——轻松实现&nbsp;Web&amp;n…
查看>>
yaf使用小记
查看>>
document.domain&nbsp;跨域问题
查看>>
window安装PHP的redis扩展
查看>>
给网站选择一个好的jquery库远程调…
查看>>
flash&nbsp;as&nbsp;与js通信(转)
查看>>
Linux系统手动安装rzsz&nbsp;软件包
查看>>
PHP的事务处理机制
查看>>
JS&nbsp;moveStart和moveEnd方法
查看>>
thrift的lua实现
查看>>
编写高性能的Lua代码
查看>>
Python正则表达式指南
查看>>
LUA--thrift--lib库的创建生成
查看>>
Shell开启扩展模式匹配shopt -s extglob
查看>>
浅谈 URI 及其转义
查看>>
nginx 优化
查看>>
openresty+lua在反向代理服务中的玩法
查看>>