歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C++ 頭文件系列(array)

C++ 頭文件系列(array)

日期:2017/3/1 9:06:40   编辑:Linux編程

注意,該頭文件僅在C++11中標准才開始出現。

簡介

與語言內置的數組一樣, array類模版支持幾乎所有內置數組包含的特性:

  • 順序的(sequence)
  • 內存連續的(contiguous storage)
  • 固定大小的(fixed-size)

那既然與內置數組一樣,為什麼還要定義這樣一個模版呢?C++委員會是想造輪子嗎(-_-)?當然不是!

為什麼需要array?

array模版類實際上是內置數組的聚合,外加一層封裝。正是由於這層接口,才使得數組能與STL接軌,真正成為一個container。

Container接口

  • array::size
  • array::back
  • array::front
  • array::empty
  • array::fill
  • ...

簡單通用的array接口,讓數組使用起來更加得心應手。 例如size()成員函數返回數組的大小,在內置數組中則只能查看數組定義或者借助外部函數。

Interator模式接口(姑且讓我這麼叫吧)

  • array::begin
  • array::end
  • array::cbegin
  • array::cend
  • array::rbegin
  • array::rend
  • array::crbegin
  • array::crend

解決語法不一致性

Iterator作為C++中溝通Algorithm與Container的橋梁,起著不可或缺的作用。然而內置類型不支持迭代器的概念,雖然對於算法來說有合適的重載能夠解決這個問題,但在語法上存在明顯的差別(vec為vector

for_each(vec.begin(), vec.end(), [](int i)
{
    //  something
});

for_each(arr, arr + 3, [](int i)
{
    //  something
});

其實不需要變量定義聲明就可以猜到,vec是container而arr不是。 這也許會阻礙代碼後期的重構與修改。使用array類模版的話就不會存在這種問題,統一的語法,多棒!

Bound Check

我們都知道,C++沿襲了C語言的設計,在access數組元素時不對數組變量進行邊界檢查。array解決了這個問題,在元素讀寫越界時會拋出異常。

差異性

與內置數組的差異

array與內置數組的一個明顯的差異就是----允許空數組的定義

至於為什麼要允許這樣一個特性,也許是:

  1. 讓空數組保持遍歷一致性
  2. 讓array容器隱式地支持清空(畢竟作為一個fixed-size container,它沒有對應的clear操作)。

然而,空數組在語義上是不允許解引用的,因此在使用時規避那些需要解引用的操作。

與其他容器的差異

該方面的差異主要體現在swap成員函數上。就像我們知道的,其他容器調用swap函數時,為了保證高效,該函數實際上執行的操作相當於交換指向實際容器內容的指針。但是array的swap函數卻是進行逐成員交換,這也許是為了保持與內置數組相同的性質----數組地址不可變

出於上述語義上的差別,array與其他容器的迭代器,在swap後會有不同的結果(深色方框代表容器對象, 方框內文字代表容器內容; 箭頭代表迭代器變量, 都指向頭元素):

swap前:

swap後:

從圖上看更為直接:

  • array模版類對象只是交換了內容而已,兩個迭代器的值都未變。
  • 其他容器對象不僅交換了內容,連迭代器的關聯性都改變了(實際上,迭代器的值(即關聯的內容)也沒變,但關聯的對象變了)。

Tuple接口

array還提供了一套獨特的tuple接口,使其能夠像使用元組那樣使用。 當然,這種可能性的前提是它本身就非常像元組。

這種特性是通過重載tuple接口的get函數,並且特化tuple_element和tuple_size類模版實現的。

Copyright © Linux教程網 All Rights Reserved