zoukankan      html  css  js  c++  java
  • C++11的一些功能

    1.断言是将一个须要为真的表达式放在语句中,在debug模式下检查一些逻辑错误的參数。C++中使用assert须要使用<assert.h>或者<cassert>头文件。有函数定义例如以下:

    void  fun(int a[],int n)
    {
    assert(n>0);
    //dosomething;
    }

    这样就能够检查n<=0的情况。假设遇到这样的情况,程序会调用abort()函数而终止。

    C++11提供了static_assert断言,它的函数原型接受两个參数,一个是断言表达式。一个是警告信息,能够用字符串表示。

    static_assert(sizeof(int)==8,”64-bitmachine should follow this”);
    int   main()
    {
    return  0;
    }

    可见。static_assert()assert提供了很多其它的信息。另外,static_assert()用于在编译期做断言推断,而assert()用于在执行期间做断言推断。

    2.__func__C++99标准中提前定义的标识符,功能是返回所在函数的名字,C++11标准中,__func__能够用于结构体中。如:

    #include <iostream>
    #include <cstdlib>
    using  namespace std;
    struct  Test
    {
    	Test():name(__func__){}
    	const  char *name;
    };
    int  main()
    {
    	Test  t;
    	cout<<t.name<<endl;
    	return  0;
    }

    3.委派构造函数

    class  A
    {
    public:
    A(){init();}
    A(int i):x(i){init();}
    A(double d ):f(d){init();}
    private:
    void  init();
    int  x;
    double  f;
    };

    上面的代码中,三个版本号的构造函数都调用了init()函数。有没有办法简化这段代码呢?

    能够使用委派构造函数:

    class  A
    {
    public:
    A(){init();}
    A(int i):A(){x=i;}
    A(double d):A(){f=d;}
    private:
    void  init();
    int  x;
    double  f;
    };

    4.初始化列表

    #include <vector>
    #include <iostream>
    using  namespace std;
    int  main()
    {
    int  a[]={1,2,3};
    int  b[]{1,2,3};
    vector<int> c{1,3,5};
    return  0;
    }

    C++11支持这样几种初始化的方式:

    赋值符号 如int  a=1+2;

    赋值符号加上初始化列表 int  a={1+2};

    圆括号 int  a(1+2);

    花括号加上初始化列表 int  a{1+2}

    5.右尖括号的改进

    template <class T>

    classA

    {};

    vector<A<int>>v;//c++98编译失败,C++11编译成功

    vector<A<int> > v;//C++98编译成功,C++11编译成功

    6.auto类型推导

    #include<iostream>
    using  namespace std;
    int main()
    {
    auto name=”world
    ”;
    cout<<”hello ”<<name<<enld;
    return 0;
    }

    auto会自己主动推导出name的类型为constchar *,然后在cout语句中输出

    基于auto的上述特点。auto能够初始化复杂类型变量,能够支持泛型编程

    7.for循环的改进

    #include <isotream>
    using namespace std;
    void action(int &e)
    {
    	cout<<e<<endl;
    }
    int main()
    {
    int arr[3]={1,2,3};
    int *p=arr;
    for(;p<a+3;++p)
    	cout<<*p<<endl;
    for_each(arr,arr+sizeof(arr)/sizeof(arr[0]),action);//for_each
    for(int &e:arr) //第二种写法
    {
    	cout<<e<<endl;
    }
    for( auto e:arr) //auto自己主动类型推导
    {
    	cout<<e<<endl;
    }
    return 0;
    }

    8.智能指针

    C++使用的是auto_ptr,C++11中它被废弃了,取而代之的是unique_ptr,shared_ptrweak_ptr,

    unique_ptr的缺点是必须独自占有内存,不能直接用=来进行赋值,并且使用move方法赋值之后。指针会失去全部权。

    #include <iostream>
    #include <memory>
    using namespace std;
    int main()
    {
    unique_ptr<int >  p1(new int(1));
    unique_ptr<int> p2=p1; //编译错。不能直接赋值
    unique_ptr<int> p3=move(p1);
    cout<<*p3<<endl;
    cout<<*p1<<endl; //执行出错。p1的全部权已经交给了p3
    return 0;
    }

    shared_ptr是表现的最像指针的智能指针。它使用引用计数来表示当前多少指针指向同一块内存,一个指针被释放。引用计数就会降低1。直到引用计数降低为0时,指针指向的内存才会真正的释放。

    weak_ptr是作为shared_ptr的辅助。它本身不会引起引用计数的添加,它能够用来检验share_ptr的有效性。

    #include <iostream>
    #include <memory>
    using  namespace std;
    void  check(weak_ptr<int> &p)
    {
    shared_ptr<int>  t=p.lock();
    if(t!=nullptr)
    cout<<”ok”<<endl;
    else
    cout<<”error”<<endl;
    }
    int  main()
    {
    shared_ptr<int>  p1(new int(1));
    shared_ptr<int>  p2=p1;
    weak_ptr<int> wp=p1;
    check(wp); //ok
    p1.reset();
    check(wp); //ok
    p2.reset();
    check(wp); 
    return  0;
    }

    9.空指针nullptr

    C++98中。空指针NULL是一个宏,类似于#define NULL0的形式,所以NULL本质上是个整型。C++11提出了nullptr取代NULL作为空的指针常量。

    nullptr相对于NULL有什么优势,能够看下这个函数重载的样例。

    void f(int i){}

    void  f(char *c){}

    f(NULL)将会调用f(int)的版本号。由于NULL0

    f(nullptr)将会调用f(char*c),由于nullptrnullptr_t类型的

    nullptrnullptr_t的关系:nullptr_t是指针类型。nullptrnullptr_t类型的常量

    nullptr_t的性质有:

    nullptr_t类型数据能够隐式转换成随意一个指针类型

    nullptr_t不能转换为非指针类型,

    nullptr_t能够用于关系运算,但不能用于算术运算

    #include <iostream>
    #include <typeinfo>
    using namespace std;
    int  main()
    {
    char*p=nullptr; //转换为指针类型
    int t=reinterpret_cast<int>(nullptr);//编译出错,nullptr_t类型不能转换为int
    nullptr_tptr;
    if(ptr==nullptr) //能够用于关系运算
    	cout<<”nullptr”<<endl;
    nullptr+=1;//编译出错,不能用于算术运算
    return  0;
    }

    10.lamda函数

    #include <iostream>
    using namespace std;
    int  main()
    {
    int  a=1;
    int  b=2;
    auto  fun=[=]()->int{return a+b;};
    cout<<fun()<<endl;;
    return  0;
    }

    auto  fun=[=]()->int{return a+b}定义了fun函数,它是lamda函数

    lamda函数的定义方法例如以下:

    [capture](parameter list) mutable ->return type {//do something;}

    有关各个字段的含义这里不再赘述。

    以下是lamdastl中应用的一个样例:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    inline  void cmp(int i)
    {
    if(i>7)
    	cout<<"larger  than  7"<<endl;
    }
    int  main()
    {
    int  a[10]={1,2,3,4,5,6,7,8,9,0};
    vector<int>  v(a,a+10);
    for(auto it=v.begin();it!=v.end();++it)
    {
    	if(*it>7)
    		cout<<"largerthan 7"<<endl;
    }
    for_each(v.begin(),v.end(),cmp);
    for_each(v.begin(),v.end(),[=](int i){
    if(i>7)
    	cout<<"largerthan 7"<<endl;
    });
    return  0;
    }

    上面的代码遍历一个容器vector,使用了三种方法,一是利用迭代器。逐个推断,二是利用仿函数,三是利用了lamda函数。



    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    leetcode
    面试知识点
    关于flock文件锁的阻塞与非阻塞
    cetos7 安装telnet
    github 获取 token
    windows安装composer
    编码问题
    RabbitMQ 关键词解释
    windows下安装rabbitmq以及php扩展amqp
    windows下安装oracle客户端和php扩展
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4654198.html
Copyright © 2011-2022 走看看