C++11 新特性整理

C++11 新特性整理

1.新类型

     新增long long和unsigned long long以支持64位的整型

     新增char16_t和char32_t以支持16位32位的字符表示

     

原始字符串

VC++ 2013现在支持原始字符串字面值了。注意:它并不支持统一码字符串字面值。一个原始字符串字面值允许你避免转义那些在HTML,XML和正则表达式里运用得得心应手的特殊字符。下面是一个示例用法:

auto s1 = R"(This is a "raw" string)";

现在,s1是一个指向常量字符串值为“This is a "raw" string”的指针。尽管不支持嵌套双引号,这与C#支持的@string文字是类似的。那么要在一个字符串字面值中嵌入R"(...)"会怎样。这种情况下,你可以使用以下语法:

auto s2 = R"QQ(Example: R"(This is my raw string)")QQ";

现在,s2包含 Example: R"(This is my raw string)"。 在这个例子中,我把QQ作为界定符。这个界定符可以是任何长度不超过16的字符串。原始字符串字面值也可以包含换行:

auto s3 = R"(<tr><td>data</td></tr>)";

最后,不论他们什么时候添加统一码字符串字面值的支持,你都可以将它们连接起来并构成原始统一码字符串字面值。


2.统一的初始化

内置变量

int x = {5};
double y {2.75};
short quar[5] {4,5,6,7,9};
int* ar = new int[4]{2,4,6,8};

类对象

Stump s1{3};
Stump s2{4,5.0};

缩窄:禁止将数值赋给无法存储它的数值变量,但允许转换为更宽的类型

char   c1{1.5f};  // error
double c2{66666}; // error

std::initializer_list:可用在构造函数的参数,列表中元素必须同一类型,或可转换为同一个类型.


3.声明

auto:自动推导类型,必须显示初始化

auto   maton      = 112;
auto   pt         = maton;          // auto 是int
double fm(double,int);    
auto   pf         = fm;             // auto 是函数指针

decltype:将变量的类型声明为表达指定的类型

decltype(x)   y;
decltype(x*n) q;
decltype(&x) pd;

应用于模板的例子:

template<typename T,typename U>
void ef(T t,U u){
    decltype(T*U) tu;
    ...
}

返回类型后置:指定返回类型

double f1(double,int);
auto f2(double,int)->double;    // 指定返回double

应用于模板的例子:

template<typename T,typename U>
void eff(T t,U u)->decltype(T*U){
  ...
}

模板别名:using =

typedef std::vector<std::string>::iterator itType; // 旧版本
using itType = std::vector<std::string>::iterator; // 新版本

新版本的模板别名可以用在模板部分具体化

template<typename T>
using arr12 = std::array<T,12>;可替换为
arr12<double>      a1;
arr12<std::string> a2;

nullptr:空指针

     消除了以前版本用NULL和0带来的问题.以前用0即可表示指针常量,又可以表示整数常量。


4.智能指针

     C++抛弃了auto_ptr,

     并新增了三种智能指针:uique_ptr,shared_ptr,weak_ptr

     所有新增的智能指针能够与STL容器和语义协同工作!


5.异常规范方面的修改

     以前:

void f501(int) throw(bad_dog);       // 捕捉类型bad_dog可能引发的异常

     新增:

void f875(short,short) noexcept;     // 指示编译器此函数不会引发异常

6.作用域内枚举

旧版枚举有以下问题:

          1.类型检查低级;

          2.同一个类中如有两个枚举,其枚举成员不能同名;

          3.枚举作用域为枚举定义所属的作用域

          4.移植性差

新版本

enum class New1{never,sometimes};
enum struct New2{newver,lever,server};

     使用是必须显示限定:New1::never


7.对类的修改

explicit:禁止单参数构造函数导致的自动转换符

类内成员初始化

class Test1
{
public:
    Test1(int n)
    {
        num=n;
    }//普通构造函数
private:
    int num;
};

class Test2
{
public:
    explicit Test2(int n)
    {
        num=n;
    }//explicit(显式)构造函数
private:
    int num;
};



int main()
{
    Test1 t1=12;//隐式调用其构造函数,成功
    Test2 t2=12;//编译错误,不能隐式调用其构造函数
    Test2 t2(12);//显式调用成功
    return 0;
}

8.模板和STL方面修改

(1)for循环

int arr[5]{1,2,3,4,5};
for(int x:arr){
    
}

(2)新的STL容器

          forward_list                    单向链表

          unordered_map               

          unordered_multimap

          unordered_set

          unordered_multiset

(3)新的STL方法

          cbegin(),cend(),crbegin(),crend(),这些新方法将元素视为const

(4)export关键字的功能被停用,但关键字还保留

(5)valarray升级:用于基于范围的STL算法,新增begin()和end()方法,它们接收一个valarray对象参数

(6)尖括号:为了于运算符>>混乱,新标准要求在声明嵌套模版时使用空格将艰苦尖括号分开

          std::vector<std::list<int>空格> v1;


9.右值引用

1.左值可以归纳为:左值表示程序中必须有一个特定的名字引用到这个值。

2.右值引用的是地址里的内容,所以相反右值可以归纳为:右值表示程序中没有一个特定的名字引用到这个值除了用地

   址,例如:x+y所产生的数据使用&&表示,右值引用可关联到右值,即可出现在赋值表达式右边,但不能对其应用地址

   运算符的值。

例子:

int x        =10;
int y        = 23;
int && r1    = 14;
int && r2    = 31;
double && r3 = std::sqrt(2.0);

10.移动语句

     举例说明:

     例子:在旧版本中复制大量对象到新地址后,再删除的过程

     内存分析:先复制这些内存信息到新的地址,然后再删除原来的地址中的内存信息.

     新增功能:把原来内存信息保留,将删除与之关联的变量记录

     以上的新增功能称为移动语义,他避免了移动原始数据,只是修改了记录.

     移动语句是通过右值引用来达成的!

     class AA{

     public:

          AA(AA&&  a1){};     // 移动构造函数

     }


11.赋值

     移动语义也适用于赋值运算符.即重载赋值运算符,然后参数为T&&


12.强制移动

     让左值强制变成右值使用.

     1.#include<utility>

     2.使用std::move(左值)


13.特殊的构造函数

     1.如果类没有提供复制构造函数,编译器将提供一个默认的.

     2.如果类没有提供移动结构函数,编译器将提供一个默认的.

     3.如果类提供了复制构造函数,析构函数,复制赋值运算符,编译器将不会自动提供移动构造函数和移动赋值运算符.

     4.如果类提供了移动构造函数或移动赋值运算符,编译器将不会提供复制构造函数和复制赋值运算符.


14.默认的方法和禁用的方法

     使用关键字default显式第声明这些方法的默认版本,即告诉编译器为函数生成默认实现

class AA{
    AA()=default;        // 默认方法
    AA(AA&&){}
    AA(const AA&)
}

     使用关键字delete来用于使编译器禁止使用特定的方法.

class AA{
    AA(double)=delete;    // 禁用方法
    AA(int){}
}

     default只能用于6个特殊成员函数.

     delete用于任何成员函数.


15.委托构造函数

     允许你在一个构造函数的定义中使用另一个构造函数.

     这样构造函数暂时将创建对象的工作委托给另一构造函数.

class AA{
    AA();
    AA(int);
    AA(int,double);
};
AA(int kk):AA(kk,0.01){}     // AA(int) 委托给 AA(int,double)


16.继承函数

class C1{
public:
    int fn(int j);
    double fn(double w);
    void fn(double char* s);
};

class C2{
public:
    using C1::fn;        // 继承C1的fn
    double fn(double dd){return dd;};
};
     
C2 c2;
int k = c2.fn(3);        // 继承C1的fn
double z = c2.fn(2.4);

这种方法用于构造函数,可让派生类继承基类的所有构造函数.(包括复制构造函数,移动构造函数...)


17.Lambda函数

     一种定义和应用函数的数学系统,这个系统让你用匿名函数。

     普通函数:bool f3(int x){return x%3 == 0;}

     lambda:[](int x){return x%3 == 0;}

     分析:[]代替了函数名,返回值相当使用了decltyp进行推导

     用途:通过使用lambda来替换函数指针或函数符构造函数!

     例如:[](double x)->double{int y=x;return x-y;}相当于

               double  dd(double x){

                    int y=x;

                    return x-y;

               }

     lambda的优点:

     1.距离:在函数调用时直观的给出定义,省的去跳转到函数体

     2.简洁:语句简明

                    auto mod3 = [](int x){return x%3 == 0;}

                    count1 = std::count_if(n1.begin(),n1.end(),mod3);

     3.效率:函数符和lambda不会阻止内联

     4.功能:可访问作用域内任何动态变量

                    [z] 按值访问,z是变量的名称

                    [&count] 按引用访问,count是变量的名称

                    [&] 按引用访问所有动态变量

                    [=] 按值访问所有动态变量

                    [z,&count] 混合用法


18.包装器

     这些包装器对象用于给其他编程接口提供更一致更合适的接口.

     bind:可以让接收几个参数的函数与STL算法匹配

     mem_fn:让成员函数作为常规函数进行传递

     reference_wrapper:创建行为像引用但可被复制的对象

     function:以统一的方式处理多种类似于函数的形式


19.可变参数模板

     让你能够创建可变数量的参数的模板函数和模板类.

     template<typename... Args>

     void show_list(Args... args){

     }

     show_list(5,'L',0.5);


其他功能

     并行编程

      ...


    

    


转载于:https://my.oschina.net/Ccx371161810/blog/422822

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值