C++ 11语法甜点1

转自:http://www.cnblogs.com/hujian/archive/2012/02/20/2358853.html


C++ 11中引入了许多简化编程工作的语法上的新特性,我们暂且美其名曰“语法甜点”。下面一一进行介绍。
      语法甜点1:序列for循环
      序列for循环是一种简化的for循环,可用于遍历一组序列,包括各种容器、string、数组、初始化列表以及由begin和end函数定义的序列。示例代码如下:

1  vector< int> vctTemp{ 123};
2   for (auto a : vctTemp)
3  {
4   cout << a << endl;
5  }

 

      语法甜点2:委托构造函数
      在引入C++ 11之前,如果某个类有多个重载的构造函数,且这些构造函数中有一些共同的初始化逻辑,通常都需要再编写一个带参数的初始化函数,然后在这些构造函数中调用这个初始化函数。在C++ 11中,再也不用这么麻烦了。我们可以实现一个最基础的构造函数,其他构造函数都调用这个构造函数。示例代码如下:

复制代码
 1  class CPerson
 2 {
 3  public:
 4  CPerson() : CPerson( 0"") { NULL; }
 5  CPerson( int nAge) : CPerson(nAge,  "") { NULL; }
 6  CPerson( int nAge,  const  string &strName)
 7  {
 8   stringstream ss;
 9   ss << strName <<  " is  " << nAge <<  " years old. ";
10   m_strInfo = ss.str();
11  }
12 
13  private:
14   string m_strInfo;
15 };
复制代码

     

      语法甜点3:统一的初始化语法
      在引入C++ 11之前,有各种不同的初始化语法。在C++ 11中,仍可以使用这些初始化语法,但也可以选择使用新引入的统一的初始化语法。统一的初始化语法用一对大括号{}表示,使用{}初始化语法还可有效地避免窄转换。示例代码如下:

复制代码
1   int a{ 5};
2   char c{ ' X '};
3   int p[ 5] = { 12, 345};
4  vector< int> vctTemp{ 123};
5  CPerson person{ 10" Mike "};
6    int b =  5.3;                      //  b赋值成5,发生了窄转换
7    int d{ 5.3};                       //  会提示编译错误,避免了窄转换
复制代码

 

      语法甜点4:nullptr
      nullptr是C++ 11中新加的一个关键字,用于标识空指针。引入nullptr后,可以解决某些函数重载时的二义性问题。示例代码如下:

复制代码
 1  void F( int a)
 2 {
 3  cout << a << endl;
 4 }
 5 
 6  void F( char *p)
 7 {
 8  assert(p != NULL);
 9 
10  cout << p << endl;
11 }
12 
13  int main( int argc, _TCHAR* argv[])
14 {
15   int *p = nullptr;
16   int *q = NULL;
17   bool bEqual = (p == q);   //  两个指针值是相等的,bEqual为true
18   int a = nullptr;    //  编译失败,nullptr不是转换为int
19 
20  F( 0);           //  在C++ 98中编译失败,有二义性;在C++ 11中调用F(int)
21  F(nullptr);     //  调用F(char *)
22 
23  getchar();
24   return  0;
25 }
复制代码

     

      语法甜点5:成员变量初始化
      与Java和C#中的用法一样,可以对成员变量进行就地初始化。示例代码如下:

1  class CPerson
2 {
3  private:
4   int m_nAge =  10;
5   string m_strName =  " Mike ";
6 };

 

      语法甜点6:默认或禁用函数
      当我们定义了自己的带参数的构造函数时,编译器将不再生成默认的构造函数,如果此时想使用默认的构造函数,则必须显式地声明并定义不带参数的构造函数。在C++ 11中,我们可以使用default关键字来表明我们希望使用默认的构造函数。类似的,当我们不想外部使用编译器自动生成的构造函数或赋值函数时,我们一般需要将其声明成protected或private的。在C++ 11中,我们可以使用delete关键字来表明我们不希望编译器生成默认的构造函数或赋值函数。示例代码如下:

1  class CPerson
2 {
3  public:
4  CPerson() =  default;
5  CPerson( const CPerson &person) = delete;
6 };

 

      语法甜点7:继承的构造函数
      当一个派生类的某个函数隐藏了基类中的某个同名函数时,如果我们想在派生类中导出基类中的这个同名函数,可以通过using Base::Func的方式将基类中的这个同名函数引入到派生类的作用域内。当该方法只对普通成员函数有效,不能用于构造函数。在C++ 11中,如果派生类认为基类的构造函数已经足够,则也可以使用using Base::Base的方式将基类的构造函数引入到派生类的作用域内。但需要注意的是,此时派生类中的成员变量并没有进行初始化,所以应当对这些成员变量进行就地初始化。示例代码如下:

复制代码
 1  class CBase
 2 {
 3 };
 4 
 5  class CDerived :  public CBase
 6 {
 7  public:
 8   using CBase::CBase;
 9  CDerived( int nData) : m_nData(nData) { NULL; }
10 
11  private:
12   int m_nData =  10;
13 };
复制代码

 

      语法甜点8:模板右边双括号
      在C++ 98中,vector<vector<int>> vctTemp是一个非法的表达式,编译器会认为右边的>>是一个移位操作符,因此必须修改为vector<vector<int> > vctTemp,即在右边的两个>中间添加一个空格。在C++ 11中,这将不再是一个问题,编译器将能够识别出右边的双括号是两个模板参数列表的结尾。

 

      语法甜点9:static_assert
      静态断言static_assert由一个常量表达式和一个字符串构成。在编译期间,将计算常量表达式的值,如果为false,字符串将作为错误信息输出。示例代码如下:

1   char a =  10;
2  static_assert( sizeof(a)== 4" a is not an integer. ");

 

      语法甜点10:初始化列表
      在引入C++ 11之前,只有数组能使用初始化列表。在C++ 11中,vector、list等各种容器以及string都可以使用初始化列表了。初始化列表对应的类为initializer_list,vector、list等各种容器以及string之所以可以使用初始化列表,是因为它们重载了参数类型为initializer_list的构造函数(称为初始化列表构造函数)和赋值函数(称为初始化列表赋值函数)。下面是一些使用初始化列表的例子。

复制代码
 1  void Print( const initializer_list< int> &ilData)
 2 {
 3   for (auto a : ilData)
 4  {
 5   cout << a << endl;
 6  }
 7 }
 8 
 9  int main( int argc, _TCHAR* argv[])
10 {
11  vector< int> vctNum = { 12345};
12  map< stringstring> mapID2Name = {{ " 92001 "" Jack "}, { " 92002 "" Mike "}};
13   string strText{ " hello world "};
14  Print({});
15  Print({ 12});
16  Print({ 12345});
17 
18  getchar();
19   return  0;
20 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值