C++11新标准总结

C++11新标准

C++11新标准出现已久,在此主要对它做一个总结:

1、C++11新功能简介

1.1 新类型

C++11新增类型long long和unsigned long long,以支持64位的整型,char16_t,char32_t,以支持16位和32位的字符表示。

1.2 统一的初始化

用大括号括起来的列表(初始化列表)的适用范围,使其可用于所有内置类型和用户定义的类型。使用列表初始化的时候可以加等号(=),也可以不添加:
int x = {10};
double y{2.75};
short quar[5]{4,5,2,67,12};
另外,列表初始化的用法也可用与new表达式中:
int *arr = new int[3]{1,2,3};
在创建对象的时候,使用大括号括起来的列表来初始化构造函数:
class Stump
{
    private:
        int root;
        double weight;
    public:
    Stump(int _r,double _w):root(r),weight(_w){}
}
Stump s1(3,1.5);//old style
Stump s2{5,4.5};//C++ 11
Stump s3 = {4,4.5};//C++ 11
用初始化列表可以防止缩窄,即禁止数值赋给无法存储它的数值变量。
char c1 = 1.57e27; //double-to-char, 可以编译通过
char c2 = 789123456; //int-to-char, 可以编译通过

//然而如果使用列表初始化语法,编译器将禁止进行这样类型转换
char c1{1.57e27}; //double-to-char, compile-time error
char c2{789123456}; //int-to-char, out-of-range, compile-time error

//但允许转换为更宽的类型,同时,只要值在较窄类型的取值范围内,将其转换为较窄的类型也是允许的:
char c1{66}; //int-to-char, in range, allowed
double c2 = {66}; //int-to-double, allowed
模板类std::initializer_list,可将其作为构造函数的参数:
#include<initializer_list>
double sum(std::initializer_list<double> il)
{
    double tot = 0;
    for(auto p=il.begin();p!=il.end();p++)
        tot+=*p;
    return tot;
}
int main()
{
    double total = sum({2,3,4,5,6});
}

1.3 声明

C++ 11提供了简化的声明功能:
1、auto
以前,关键字auto是一个存储类型的说明符,C++ 11将其用于实现自动类型推断,这要求进行显式初始化,让编译器能够将变量的类型设置为初始值的类型:
auto maton = 112;//maton is type int
auto pt = &maton; //pt is type int *
double fm(double,int);
auto pf = fm;
2、decltype
关键字decltype将变量的类型声明为表达式指定的类型。下面的语句的含义是,让y的类型与x的类型相同,其中x是一个表达式:
decltype(x) y;
//samples
double x;
int n;
decltype(x*n) q;
decltype(&x) pd;
    //这在定义模板时很有用,因为只有等到模板被实例化时才能确定类型:
template<typename T,typename U>
void ef(T t, U u)
{
    decltype(T*U) tu;
    ...
}
int j=3;
int &k=j;
const int &n = j;
decltype(n) i1;//i1 type const int &
decltype(j) i2;//i2 type int
decltype((j)) i3;//i3 type int &
decltype(k+1) i4;//i4 type int
3、返回后置类型
C++ 11新增了一种函数声明的语法:在函数名和参数列表后面(而不是前面)指定返回类型:
double f1(double,int);
auto f2(double,int)->double;
//这种用法比较适合于模板中:
template<typename T,typename U>
auto eff(T t,U u)->decltype(T*U)
{}
4、模板别名:using=
对于冗长或复杂的标识符,如果能够被创建其别名将很方便。以前,C++为此提供了typedef:
typedef std::vector<std::string>::iterator itType;
using itType = std::vector<std::string>::iterator;
//差别在于,using可用于模板部分具体化,但typedef不能
template<typename T>
using arr12 = std::array<T,12>;
//上述语句具体化array<T,int>(int = 12)。
std::array<double, 12> a1;
std::array<std::string,12> a2;
//可将它们替换为如下声明:
arr12<double> a1;
arr12<std::string> a2;
5、nullptr
空指针是不会指向有效数据的指针,C++11新增nullptr来表示指针类型。

1.4 智能指针

C++ 中引入智能指针auto_ptr,实现自动内存释放,在C++11开始摒弃了这种用法,新增了3种智能指针:unique_ptr、shared_ptr、weak_ptr。
std::shared_ptr 是一种智能指针,它能够记录多少个 shared_ptr 共同指向一个对象,从而消除显示的调用 delete,当引用计数变为零的时候就会将对象自动删除,std::unique_ptr 是一种独占的智能指针,它禁止其他智能指针与其共享同一个对象,从而保证了代码的安全,std::weak_ptr防止相互引用导致内存无法释放。

1.5 异常规范方面的修改

之前,C++提供了异常规范,用来之处哪些函数可能引发哪些异常:
void f501(int) throw(bad_dog);
void f733(long long ) throw();
//在C++ 11中摈弃了这种用法,增加关键字noexcept,用来表示某个函数不会发生异常:
void f875(short,short) noexcept;

1.6 作用域内枚举

之前的枚举类型的作用域为枚举定义所属的作用域,这意味着如果在同一个作用域内定义两个枚举,它们的枚举成员不能同名。C++ 11可以使用class或struct定义枚举:
enum old{year,month,day};
enum class new1{year,month,day};
enum struct new2{hour.minute,second};

1.7 对类的修改

为简化和扩展类设计,c++11做了多项改进,包括构造函数的继承和彼此的调用
~~未完待续~~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值