12.21 淺談C++ initialize

淺談initialize_list原理

自從C++11 開始,初始化就引入了一個新的特性,如下:

淺談C++ initialize_list原理

​可以直接通過一個初始化列表來初始化容器,那麼這個是怎麼實現的呢?這就和我們今天要說的initializer_list有關了。

1. 引入

先看一個情況,在C語言中,如果我們想要實現一個可變形參的函數,那麼應該這麼做:

淺談C++ initialize_list原理

​這裡函數必須聲明稱C調用約定,至於原因,跟棧平衡恢復有關,這裡不細講。

當然在C++中,也可以使用這種情況,不過C++可以使用另外一種技術實現,就是initializer_list,下面我們看一下這種技術的基本使用和原理。

2. initializer_list

2.1 簡介

先來看一下C++網站對於這種結構的描述:

This type is used to access the values in a C++ initialization list, which is a list of elements of type const T.

Objects of this type are automatically constructed by the compiler from initialization list declarations, which is a list of comma-separated elements enclosed in braces:

淺談C++ initialize_list原理

​從這裡我們可以知道,這種類型是編譯器自動構造的。

2.2 基本使用

這個類提供瞭如下的操作接口

淺談C++ initialize_list原理

​關於構造函數,我們有如下構造方法:

1.initializer_list li : 構造一個空的列表。

2.initializer_list li{a, b, c, ...} : 構造一個指定的列表。

2.3 示例

那麼 initializer_list具體怎麼使用呢?下面給出一個基本的使用例子:

淺談C++ initialize_list原理

​2.4 原理

先看一下initializer_list的實現過程:

淺談C++ initialize_list原理

淺談C++ initialize_list原理

​從這裡我們可以發現如下問題:

1.保存const的變量的指針(起始和結束)。

2.構造函數initializer_list() noexcept.

3.構造函數initializer_list(const _Elem *_First_arg, const _Elem *_Last_arg) noexcept

4.initializer_list保存的元素應該是一樣的。

從上分析,initializer_list沒有類似initializer_list(int, int, int, ...)的構造函數,那麼對於initializer_list li = {100, 200, 300, 400, 500}是怎麼初始化的呢?

最好的辦法就是看看反彙編代碼,在VS編譯器中(每個編譯器的實現可能會不同):

淺談C++ initialize_list原理

​原理為:

1.在棧上面分配一個數組。

2.取到數組的第一個和最後一個地址的下一個(ebp-18h, ebp-2Ch).

3.然後調用構造函數initializer_list(const _Elem *_First_arg, const _Elem *_Last_arg) noexcept。

也就是說,編譯器底層幫忙做了所有的事情。

唉,有人說C++真的很難,我覺得編譯器做了太多的事情,也是導致C++難學的原因;因為編譯器做得事情越多,使用起來就會越方便,但是理解起來就更加困難。

3. 應用

3.1 容器的使用

在vector中存在如下的構造函數

淺談C++ initialize_list原理

​那麼,我們就可以使用:

淺談C++ initialize_list原理

​編譯器幫我們做得事情:

淺談C++ initialize_list原理

​3.2 項目使用

我們可以在自己的類或者函數中實現這一個特性,例如:

淺談C++ initialize_list原理

​反彙編結果如下:

淺談C++ initialize_list原理

​4. 總結

C++編譯器總是瞞著我們做了太多的事情,所有導致我們知其然而不知其所以然;導致我們C++使用越來越簡單,理解起來就會越來越複雜;導致我們編寫C++越來越簡單,但是寫出高效的C++代碼就會越來越困難。


分享到:


相關文章: