C++ 11新特性记录

    一直在使用C++11,某日被问到C++ 11 有哪些新特性时,茫然了,特做补充总结

来源于 C++ Primer Plus(第6版)中文版

1. auto关键字

  要求显示初始化,让编译器能够将变量的类型设置为初始值的类型 
auto maton=112//maton is type int 
auto pt=&maton;    //pt is  type int *
double fm(double ,int );
auto pf=fm; //pf is type double(*)(double,int)
//关键字简化模板声明
//如果il是一个std::initalizer_list <double>对象,则可使用如下表达式
for(std::initializer_list<double>::iterator p=il.begin();p!=il.end();p++)
//替换为如下
for(auto p=il.begin();p!=il.end();p++)

2. decltype关键字

 关键字字decltype将变量的类型申明为表达式指定类型
decltype (x)  y;
double x;
int n;
decltype(x*n) q;//q same type as x*n, i.e., double
decltype(&x) pd;//pd same type ad &x.,i.e.double*
//定义模板是很有用,因为只有模板实例化时才能却定类型
template<typename T,typename U>
void ef(T t,U u)
{
decltype(T*U) tu;
}

3. 返回类型后置

在函数名和参数列表后面 指定返回类型
double  f1(double,int );//traditional syntax
 auto f2(double ,int )->double; //new syntax, return type is double

4. 模板别名: using=

	//以前C++ 提供typedef:
 	typedef std::vector<std::string>::iterator itType;
 	//C++ 11 提供另一种创建别名的语法
 	using itType =std::vector<std::string>::iterator;
 	//新语法的优点,在于可以用于模板部分具体化,但typedef不能

5. nullptr

空指针是不会指向有效数据的 指针。以前,C++在源代码中使用0表示这种指针,但内部表示可能不同。这带来一些问题,因为这使得0即可表示指针常量,又可表示整型常量。so C++新增了关键字nullptr,用来表示空指针,因此nullptr==0 为true,但使用nullptr而不是0 提供了更高的类型安全。
例如:可将0传递给接受int参数的函数,但如果您将nullptr传递给这样的函数,编译器会对此视为错误。因此处于清晰和安全考虑,请使用nullptr

6. 智能指针

	如果在程序中使用new从堆(自有存储区)分配内存,等到不需要时,应使用delete将其释放。C++引入了智能指针auto_ptr,以帮助自动完成这个过程。随后的编程体验表明,需要有更精致的机制。基于程序员的编程体验和boost库提供的解决方案,C++摒弃了auto_ptr,并新增了三种智能指针:unique_ptr、shared_ptr和weak_ptr。

7. 作用域内枚举

 传统的C++枚举提供了一种穿件名称常量的方式,但器类型检查相当低级。另外枚举名的作用域为枚举定义所属作用域,这意味着,如果在同意作用域内定义两个枚举,他们的枚举成员不能同名。最后枚举可能不是可完全移植的,因为不同的实现可能选择不同的底层类型。为了解决这一问题,C++新增了一种枚举。这种枚举使用class和struct定义:
num Old1{yes,no,maybe};
 enum class New1 {never,sometimes,often,always};
 enum struct New2 {never,lever,sever};

新枚举要求进行显示定义,以免发生名称冲突。因此,引用特定枚举时,需要使用New1::never 和 New2::never等。

8. 对类的修改

 为了简化和扩展类设计,C++11做了多项改进。这包括允许构造函数被集成和彼此调用、更佳的方法访问控制方式及移动构造函数和移动赋值运算符
  1. 显示转换运算符
    C++ 很早就支持对象自动转换,但随着编程经验的积累,程序员逐渐认识到,自动类型转换可能导致意外转换的问题。为了将诶绝这种问题,C++引入关键字 explicit,以禁止单参数构造函数导致的自动转换:
class Plebe
 {
 Plebe(int);//automatic int -to -plebe conversion
 explicit Plebe(double);//requires explicit use
 };
 Plebe a,b;
 a=5;//implicit conversion,call Plebe(5)
 b=0.5; //not allowed
 b=Plebe(0.5);//explicit conversion

C++ 1 1扩展了explicit 的这种用法,使得可对转换函数做类似的处理

class Plebe
{
...
//conversion  functions
operator int () const;
explicit operator  double () const;
......
};
.....
plebe a,b;
int n=a;
double x=b;//not allowed
x=double(b)//explicit conversion allowed
  1. 类内成员初始化
class Session
   {
	   int mem1 = 10; //in-class initialization
	   double mem2{1996.54};
	   short mem3;
    public:
    Session(){}
    Session(short s):mem3(3) {}
    Session(int n ,double d,short s):mem1(n),mem2(d),mem3(s){}
    .......
   }

9. 模板和STL方面修改

  1. 基于范围的for循环
    对于内置数组以及包含方法begin()和end()的类(如std::string)和STL容器,基于范围的for循环可简化编写循环的工作,这种循环对数组或容器中的每个元素执行指定操作:
double prices[5]={4.99,10.99,6.87,7.99,8.49};
		for (auto x :prices)
		    cout<< x <<endl;
如果要在循环中修改数组或者容器的没个元素,可以使用引用类型
std::vector<int > vi(6);
for (auto &x :vi)
    x=std::rand();
  1. 新的STL容器
    C++ 11 新增了容器forward_list、unordered_map、unordered_multimap、unordered_set和unordered_multiset。

  2. 新的STL方法
    C++ 11新增了STL方法cbegin()和cend() 。与begin()和end()一样,也是返回一个迭代器指向容器的第一个元素和最后一个元素的后面,因此可以用于指定包含全部元素的区间。另外这些新方法将元素视为const。

  3. valarray升级
    模板valarry独立与STL开发的,其最初的设计导致无法将基于范围的STL算法用于vslarry对象,。C++添加了两个函数(begin()和end()),他们都接受valarry作为参数,并返回迭代器,这些迭代器分别指向valarry对象的第一个元素和最后一个元素后面,

  4. 摒弃export
    c++98 新增了关键字export,旨在提供一种途径,让程序员能够将模板定义放在接口文件和实现文件中,其中前者包含原型和模板申明,而后者包含模板函数的方法和定义。实践证明这不现实,因此C++ 11终止了这种用法,但扔保留关键字export 供以后使用。

  5. 尖括号
    为了避免与运算符>> 混淆,C++要求在申明嵌套模板是使用空格将尖括号分开:
    std::vector<std::list > v1;//
    C++ 11 中不在这样要求
    std::vector<std::list > v1;// >>ok in C++11

10.右值引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值