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<int, int> m;
auto it = m.find(42);
//C++98: std::map<int, int>::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<int> bigVector;
for (unsigned i = 0; i < bigVector.size(); ++i)  // 對於大尺寸數組,這個循環變成了一個無限循環
{ ... }

std::vector<int> 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<uint8, 16> 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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章