C++11增加的功能特性

本文来自对C++官网中《Published by PVSCoder Sep 16, 2016 (last update: Sep 16, 2016) How to avoid bugs using modern C++》的翻译
Published by PVSCoder Sep 16, 2016 (last update: Sep 16, 2016) How to avoid bugs using modern C++

“现代C++”这个术语在C++11发布后变得非常流行。这是什么意思?首先,现代C++是一组模式和习语,旨在消除的缺点美好的“C类”,如此多的C++程序员使用,特别是如果他们开始在C,C++编程11看起来更简洁易懂的方式,这是非常重要的。
C++11增加的功能特性包括:自动类型推断;lambdas表达式;

1、自动类型推断

C++11新增加了auto和decltype关键字。

std::map m;
auto it = m.find(42);
//C++98: std::map::iterator it = m.find(42);

在不影响代码的可读性的情况下,缩短长类型是非常方便的。然而,这些关键字与模板一起变得非常广泛,没有必要用auto和decltype指定返回值的类型。
在64位系统中,下面的代码会出错:

string str = .....;
unsigned n = str.find("ABC");
if (n != string::npos)

在64位系统下,string::npos的值要远大于Unix系统中对于unsigned类型的最大限定值。auto可以解决这个问题,变量n的类型对程序员而言并不重要,我们需要做的就是让它适配string::find所有可能的取值。

string str = .....;
auto n = str.find("ABC");
if (n != string::npos)

使用auto依然会有很多陷阱:

auto n = 1024 * 1024 * 1024 * 5;
char* buf = new char[n];

若本地内存小于5GB,auto无法解决溢出的问题。
auto也无法解决错误循环的问题:

std::vector bigVector;
for (unsigned i = 0; i < bigVector.size(); ++i)  // 对于大尺寸数组,这个循环变成了一个无限循环
{ ... }

std::vector bigVector;
for (auto i = 0; i < bigVector.size(); ++i)
{ ... }

2、数组

在标准C中,将数组作为实参传给函数时,需要意识到传给函数形参的是一个指针,需要用sizeof计算数组的成员的数量。

#define RTL_NUMBER_OF_V1(A)      (sizeof(A)/sizeof((A)[0]))
#define _ARRAYSIZE(A)     RTL_NUMBER_OF_V1(A)

int GetAllNeighbors( const CCoreDispInfo *pDisp,
                     int iNeighbors[512] ) {
  ....
  if ( nNeighbors < _ARRAYSIZE( iNeighbors ) ) 
    iNeighbors[nNeighbors++] = pCorner->m_Neighbors[i];
  .... 
} 

但是在sizeof (iNeighbors)中,使用sizeof计算的是指针的长度,而不是数组的长度。int iNeighbors[512]在参数中直接说明数组的长度没有发挥任何作用,除了给我们提醒。

使用 C++中的std::array可以避免传统数组的很多问题,它拥有类似vector容器的很多API。

void Foo(std::array array)
{
 	 array.size(); //=> 16
}

3、enum类型的使用改进

enum iscsi_param {
  ....
  ISCSI_PARAM_CONN_PORT,
  ISCSI_PARAM_CONN_ADDRESS,
  ....
};
 
enum iscsi_host_param {
  ....
  ISCSI_HOST_PARAM_IPADDRESS,
  ....
};

int iscsi_conn_get_addr_param(....,
  enum iscsi_param param, ....)
{
  ....
  switch (param) {
  case ISCSI_PARAM_CONN_ADDRESS:
  case ISCSI_HOST_PARAM_IPADDRESS:
  ....
  }
  return len;
}

上面函数中的参数中,枚举变量来自不同的枚举结构,产生多种不同的情况,是一个隐性错误,但是只会给出warning警告。
在C++11中,您可以并且应该使用enum类:这样的技巧在那里不起作用,并且错误将出现在编译阶段。

enum class ISCSI_PARAM {
  ....
  CONN_PORT,
  CONN_ADDRESS,
  ....
};
 
enum class ISCSI_HOST {
  ....
  PARAM_IPADDRESS,
  ....
};

int iscsi_conn_get_addr_param(....,
 ISCSI_PARAM param, ....)
{
  ....
  switch (param) {
  case ISCSI_PARAM::CONN_ADDRESS:
  case ISCSI_HOST::PARAM_IPADDRESS:
  ....
  }
  return len;
}

4、智能指针auto_ptr

在C++11中被声明弃用,在C++17中被删除。unique_ptr取代了auto_ptr。

你可能感兴趣的:(c++)