C++11系列學(xué)習(xí)之列表初始化
前言:
由于舊標(biāo)準(zhǔn)初始化方式太過(guò)繁雜,限制偏多,因此在新標(biāo)準(zhǔn)中統(tǒng)一了初始化方式,為了讓初始化具有確定的效果,于是提出了列表初始化概念。
舊標(biāo)準(zhǔn)初始化方式
普通數(shù)組初始化:
int i_arr[3] = {1, 2, 3}
POD類型初始化(即plain old data類型,可以直接使用memcpy復(fù)制的對(duì)象):
struct A { int x; struct B { int i; int j; } b; } a = {1, {2, 3}};
拷貝初始化:
int i = 0; class Foo { public: Foo(int) {} } foo = 123
直接初始化:
int j(0) Foo bar(123)
C++11標(biāo)準(zhǔn)初始化方式
C++11標(biāo)準(zhǔn)中{}的初始化方式是對(duì)聚合類型的初始化,是以拷貝的形式來(lái)賦值的。
C++11標(biāo)準(zhǔn)中對(duì)非聚合類型則以構(gòu)造函數(shù)來(lái)進(jìn)行初始化的。
聚合類型:
- 類型是一個(gè)普通的數(shù)組
- 類型是一個(gè)類,
并且滿足以下條件:
- 無(wú)用戶自定義的構(gòu)造函數(shù)
- 無(wú)私有或保護(hù)的非靜態(tài)數(shù)據(jù)成員
- 無(wú)基類
- 無(wú)虛函數(shù)
- 不能有 { } 和 = 直接初始化的非靜態(tài)數(shù)據(jù)成員
初始化列表技術(shù)細(xì)節(jié)
觀察下面這兩個(gè):
int arr[] {1, 2, 3} std::set<int> ss = {1, 2, 3}
之所以可以實(shí)現(xiàn)STL中不指定個(gè)數(shù)進(jìn)行初始化,依賴的就是與i個(gè)輕量級(jí)的類模板,也是C++11中的新特性std::initializer_listinitializer_list使用
class FooVector { std::vector<int> content_; public: FooVector(std::initializer_list<int> list){ //重要技術(shù)點(diǎn) for(auto it = list.begin(); it != list.end(); ++it){ content_.back(*it) } } } FooVector foo_1 = {1, 2, 3, 4, 5} //不僅可以這樣 FooVector foo_2({1, 2, 3, 4, 5}) //還可以傳一個(gè)同種類型數(shù)據(jù)集合
initializer_list的特點(diǎn):
- 它是一個(gè)輕量級(jí)的容器類型,內(nèi)部定義了
iterator
等容器必需的概念 - 對(duì)于
std::initializer_list
來(lái)說(shuō),它可以接收任意長(zhǎng)度的初始化列表,但要求元素類型必須是同種類型T(或者可轉(zhuǎn)換為T(mén)) - 它有3個(gè)成員接口:size () 、 begin() 、end()
- 它只能被整體初始化或賦值
注意:std::initializer_list 是非常高效的,因此內(nèi)部并不負(fù)責(zé)保存初始化列表中的元素的拷貝,而是僅僅存儲(chǔ)列表中元素的引用!因此不能用來(lái)返回臨時(shí)變量!
避免類型收窄:
C++有隱式類型轉(zhuǎn)換的特性,比如將一個(gè)浮點(diǎn)數(shù)賦值給一個(gè)整數(shù),精度會(huì)丟失,小數(shù)點(diǎn)后會(huì)被直接截?cái)?。初始化列表可以幫助避免隱式類型轉(zhuǎn)換。因?yàn)槠洳辉试S這種轉(zhuǎn)換發(fā)生。
但是也會(huì)隨著編譯器的不同而不同:
float ff = 1.2 float ff = {1.2}
在gcc4.8下沒(méi)有警告和錯(cuò)誤,但Microsoft Visual C++2013中,收到編譯錯(cuò)誤。因?yàn)?.2默認(rèn)是double類型,由double轉(zhuǎn)換成float會(huì)發(fā)生隱式類型轉(zhuǎn)換,但是并沒(méi)有發(fā)生精度損失。
總結(jié)
C++11新增的初始化方式,為程序的編寫(xiě)帶來(lái)了很多的便利,這也是新標(biāo)準(zhǔn)秉承的思想和改進(jìn)的方向。
到此這篇關(guān)于C++11系列學(xué)習(xí)之列表初始化的文章就介紹到這了,更多相關(guān)C++11列表初始化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
將CString字符串輸入轉(zhuǎn)化成整數(shù)的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇將CString字符串輸入轉(zhuǎn)化成整數(shù)的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09深入理解C++中public、protected及private用法
這篇文章主要介紹了C++中public、protected及private用法,對(duì)于C++面向?qū)ο蟪绦蛟O(shè)計(jì)來(lái)說(shuō)是非常重要的概念,需要的朋友可以參考下2014-08-08200行C語(yǔ)言代碼實(shí)現(xiàn)簡(jiǎn)易三子棋游戲
三子棋(井字棋)我們的童年或多或少都體驗(yàn)過(guò)這個(gè)游戲的樂(lè)趣,本子隨手一畫(huà)就是一局游戲的開(kāi)始,下面這篇文章主要給大家介紹了關(guān)于200行C語(yǔ)言代碼實(shí)現(xiàn)簡(jiǎn)易三子棋游戲的相關(guān)資料,需要的朋友可以參考下2023-05-05Qt串口通信開(kāi)發(fā)之QSerialPort模塊簡(jiǎn)單使用方法與實(shí)例
這篇文章主要介紹了Qt串口通信開(kāi)發(fā)之QSerialPort模塊簡(jiǎn)單使用方法與實(shí)例,需要的朋友可以參考下2020-03-03C語(yǔ)言位段(位域)機(jī)制結(jié)構(gòu)體的特殊實(shí)現(xiàn)及解析
這篇文章主要為大家介紹了C語(yǔ)言位段位域機(jī)制結(jié)構(gòu)體的特殊實(shí)現(xiàn)講解有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-02-02C++中set/multiset容器詳解(附測(cè)試用例與結(jié)果圖)
set/multiset屬于關(guān)聯(lián)式容器,底層結(jié)構(gòu)是用二叉樹(shù)實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于C++中set/multiset容器的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02