欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++11中列表初始化機(jī)制的概念與實(shí)例詳解

 更新時(shí)間:2021年11月09日 15:08:15   作者:ChlorineCL  
在我們實(shí)際編程中,我們經(jīng)常會(huì)碰到變量初始化的問(wèn)題,對(duì)于不同的變量初始化的手段多種多樣,下面這篇文章主要給大家介紹了關(guān)于C++11中列表初始化機(jī)制的相關(guān)資料,需要的朋友可以參考下

概述

定義:列表初始化是C++11引入的新標(biāo)準(zhǔn),目的是統(tǒng)一初始化方式

C++11以前只能使用列表初始化來(lái)初始化內(nèi)置類(lèi)型數(shù)組和POD類(lèi)型對(duì)象,C++11中列表初始化可以用于初始化任何類(lèi)型對(duì)象

  • POD(plain old data)類(lèi)型:僅由內(nèi)置類(lèi)型變量構(gòu)成且不含指針的類(lèi),簡(jiǎn)單來(lái)說(shuō)是可以直接使用memcpy復(fù)制的對(duì)象
  • 聚合體(aggregate):聚合體一定是POD類(lèi)型
    • 無(wú)自定義構(gòu)造函數(shù)
    • 無(wú)私有或保護(hù)的非靜態(tài)數(shù)據(jù)成員(靜態(tài)成員與單獨(dú)對(duì)象無(wú)關(guān),故不影響初始化)
    • 無(wú)基類(lèi)
    • 無(wú)虛函數(shù)
    • 無(wú)類(lèi)內(nèi)已經(jīng)初始化的非靜態(tài)數(shù)據(jù)成員

注意:區(qū)分列表初始化和初始化列表

        列表初始化:用{}進(jìn)行初始化的方式

        初始化列表:構(gòu)造函數(shù)體前對(duì)對(duì)象成員直接進(jìn)行初始化的列表

        initializer_list:一種用于未定參數(shù)的輕量STL容器

實(shí)現(xiàn)機(jī)制詳解

對(duì)內(nèi)置類(lèi)型對(duì)象、POD對(duì)象和類(lèi)對(duì)象的列表初始化實(shí)現(xiàn)細(xì)節(jié)是不同的

POD類(lèi)型的列表初始化

  • 此處POD類(lèi)型包括:內(nèi)置類(lèi)型、聚合體類(lèi)
  • 內(nèi)置類(lèi)型數(shù)組按照順序初始化
    • C++11標(biāo)準(zhǔn)中列表初始化會(huì)防止可能導(dǎo)致潛在信息丟失的類(lèi)型縮?。床荒芟褓x值一樣將大類(lèi)型如int隱式轉(zhuǎn)換成小類(lèi)型如char)
  • 聚合體類(lèi)按照成員定義順序依次初始化

含有構(gòu)造函數(shù)的類(lèi)的列表初始化(C++11)

  • 通過(guò){}進(jìn)行初始化和()結(jié)果一致【即通過(guò)()調(diào)用構(gòu)造函數(shù)的地方都可以完全等價(jià)地用{}代替】,都是直接用括號(hào)內(nèi)的值調(diào)用對(duì)應(yīng)構(gòu)造函數(shù)直接初始化對(duì)象,并不會(huì)先生成臨時(shí)對(duì)象再拷貝
  • ={}與{}是等價(jià)的語(yǔ)法【即加不加=對(duì)初始化行為沒(méi)有影響】,均不會(huì)調(diào)用拷貝運(yùn)算符或拷貝構(gòu)造函數(shù)
  • 與內(nèi)置類(lèi)型的列表初始化一致,C++11的列表初始化只能用于初始化,不能用于已初始化對(duì)象的賦值
  • 實(shí)際機(jī)制猜想:傳遞的實(shí)際參數(shù)為initializer_list類(lèi)型,通過(guò)匹配重載函數(shù)實(shí)現(xiàn)調(diào)用【我不知道怎么驗(yàn)證這個(gè)過(guò)程,求大佬解答】

列表初始化用于函數(shù)返回值

  • 在返回值類(lèi)型為對(duì)象(不能是對(duì)象的引用)的函數(shù)中可以返回{}的列表初始化
  • {}返回值的實(shí)際類(lèi)型為initiallizer list(但不能聲明為std::initializer_list),相當(dāng)于返回構(gòu)造函數(shù)的表達(dá)式,因此類(lèi)型不能是對(duì)象的引用

引入std::initializer_list

  • initializer_list為一個(gè)輕量級(jí)STL模板,聲明在頭文件<initializer_list>中,定義在命名空間std中
  • 任意的STL容器都與未指定長(zhǎng)度的數(shù)組有一樣的初始化能力,可以填入任何數(shù)量的同類(lèi)型數(shù)據(jù),因此可以用STL容器輕易對(duì)固定類(lèi)型的類(lèi)進(jìn)行賦值
  • initializer_list是一個(gè)輕量級(jí)的模板,可以接受任意長(zhǎng)度的同類(lèi)型的數(shù)據(jù)也就是接受可變長(zhǎng)參數(shù),同時(shí)作為STL容器它具有STL容器的共同特征(如迭代器)
    • 只有三個(gè)成員接口:begin() end() size()
    • 只能被整體的初始化和賦值,迭代器遍歷的數(shù)據(jù)僅可讀,不能對(duì)單個(gè)數(shù)據(jù)進(jìn)行修改
  • 所有{}對(duì)象都是隱式創(chuàng)建的std::initializer_list類(lèi)型字面量(右值),廣泛用于實(shí)現(xiàn)列表初始化(不需要頭文件)

代碼驗(yàn)證

class testClass
{
private:
	int a;
	int b;
public:
	testClass() :a(0), b(0) {
		cout << "default init\n";
	}
	testClass(int a) :a(a), b(a) {
		cout << "sing-val init\n";
	}
	testClass(int a, int b) :a(a), b(b) {
		cout << "val init\n";
	}
	testClass(testClass& temp) :a(temp.a), b(temp.b) {
		cout << "copy init\n";
	}
	testClass& operator=(testClass& temp) {
		//testClass& newobj = *this;
		a = temp.a;
		b = temp.b;
		cout << "copy assign\n";
		return *this;
	}
	testClass& operator=(int x) {
		a = x;
		b = x;
		cout << "int-convert assign\n";
		//testClass& newobj = *this;
		return *this;
	}
	testClass& operator++() {
		a++;
		b++;
	}
	void printVal(ostream& os) {
		os << "a=" << a << "\n";
		os << "b=" << b << "\n";
	}
};
using tc = testClass;
tc& makeObj(int x, int y)
{
	return { x,y };
}
int main()
{
	tc a(1, 1); //val init
	tc b{ 1,1 }; //val init
	tc c = { 1,1 }; //val init
	tc d = tc{ 1,1 }; //val init
	cout << endl;
	tc* e = new tc[2]; //default init *2
	cout << endl;
	tc* f = new tc[3]{ {1,1},{2,2},{3,3} }; //val init *3
	cout << endl;
	tc* g = new tc[5]{ {1,1},{1} }; // val init + sing-val init + default init *3
	cout << endl;
	cout << "testing return val of init_list\n";
	tc h = makeObj(2, 2); //val init
	tc i = h; //copy init
	i = d; //copy assign
	i.printVal(cout);
	return 0;
}

以下為運(yùn)行截圖

列表初始化測(cè)試

添加initializer_list為參數(shù)的構(gòu)造函數(shù)后

testClass::testClass(initializer_list<int> list) :a(0), b(0)
{
	int ab = 1;
	for (auto it = list.begin(); it != list.end(); it++)
	{
		if (ab)
			a += *it;
		else
			b += *it;
	}
	cout << "init_list init\n";
}
 
int main()
{
	tc a(1, 1); //val init
	tc b{ 1,1 }; //val init
	tc c = { 1,1 }; //val init
	tc d = tc{ 1,1 }; //val init
	cout << endl;
	tc* e = new tc[2]; //default init *2
	cout << endl;
	tc* f = new tc[3]{ {1,1},{2,2},{3,3} }; //val init *3
	cout << endl;
	tc* g = new tc[5]{ {1,1},{1} }; // val init + sing-val init + default init *3
	cout << endl;
	cout << "testing return val of init_list\n";
	tc h = makeObj(2, 2); //val init
	tc i = h; //copy init
	i = d; //copy assign
	i.printVal(cout);
	cout << endl;
	cout << "testing argument init_list\n";
	tc j = { 1,2,3,4,5,6 };
	tc k = { 9 };
	return 0;
}

以下為運(yùn)行截圖


添加init_list后測(cè)試截圖

由此可見(jiàn)所有列表初始化都調(diào)用了含有initializer_list為參數(shù)的構(gòu)造函數(shù),證實(shí)了列表初始化是基于隱式轉(zhuǎn)換并以initializer_list為底層實(shí)現(xiàn)的構(gòu)想

應(yīng)用

  • 在聲明時(shí)直接初始化堆上分配的對(duì)象(數(shù)組)
    • 類(lèi):可以顯式指定使用的構(gòu)造函數(shù)(默認(rèn)會(huì)執(zhí)行無(wú)參數(shù)的構(gòu)造函數(shù))
    • 內(nèi)置類(lèi)型:可以在分配時(shí)直接指定值
  • 在函數(shù)返回對(duì)象時(shí)避免自動(dòng)存儲(chǔ)期對(duì)象銷(xiāo)毀的問(wèn)題
  • 手動(dòng)調(diào)用std::initializer_list實(shí)現(xiàn)可變參數(shù)初始化

列表初始化防止類(lèi)型收窄

C++11的列表初始化還有一個(gè)額外的功能就是可以防止類(lèi)型收窄,也就是C++98/03中的隱式類(lèi)型轉(zhuǎn)換,將范圍大的轉(zhuǎn)換為范圍小的表示,在C++98/03中類(lèi)型收窄并不會(huì)編譯出錯(cuò),而在C++11中,使用列表初始化的類(lèi)型收窄編譯將會(huì)報(bào)錯(cuò):

int a = 1.1; //OK
int b{ 1.1 }; //error
 
float f1 = 1e40; //OK
float f2{ 1e40 }; //error
 
const int x = 1024, y = 1;
char c = x; //OK
char d{ x };//error
char e = y;//error
char f{ y };//error

總結(jié)

列表初始化通過(guò)C++11引入的initializer_list容器實(shí)現(xiàn)了初始化方式的統(tǒng)一,可以看作一種語(yǔ)法糖

初始化類(lèi)對(duì)象時(shí),通過(guò)()調(diào)用構(gòu)造函數(shù)的地方都可以完全等價(jià)地用{}代替

={}不會(huì)生成臨時(shí)對(duì)象再拷貝初始化

到此這篇關(guān)于C++11中列表初始化機(jī)制的文章就介紹到這了,更多相關(guān)C++11列表初始化機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++利用GPAC實(shí)現(xiàn)生成MP4文件的示例代碼

    C++利用GPAC實(shí)現(xiàn)生成MP4文件的示例代碼

    GPAC主要針對(duì)學(xué)生和內(nèi)容創(chuàng)作者,代表了一個(gè)跨平臺(tái)的多媒體框架,開(kāi)發(fā)人員可以使用它在?LGPL?許可下制作開(kāi)源媒體。本文就來(lái)用GPAC實(shí)現(xiàn)生成MP4文件,感興趣的可以了解一下
    2023-02-02
  • OpenCV實(shí)現(xiàn)霍夫變換直線檢測(cè)

    OpenCV實(shí)現(xiàn)霍夫變換直線檢測(cè)

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)霍夫變換直線檢測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C++?BoostAsyncSocket實(shí)現(xiàn)異步反彈通信的案例詳解

    C++?BoostAsyncSocket實(shí)現(xiàn)異步反彈通信的案例詳解

    這篇文章主要為大家詳細(xì)介紹了C++?BoostAsyncSocket如何實(shí)現(xiàn)異步反彈通信,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-03-03
  • QT5.12.5移植到ARM平臺(tái)下的方法步驟

    QT5.12.5移植到ARM平臺(tái)下的方法步驟

    本文主要介紹了QT5.12.5移植到ARM平臺(tái)下的方法步驟,包括修改配置文件、代碼修改以及測(cè)試運(yùn)行,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • 淺析C/C++ 中return *this和return this的區(qū)別

    淺析C/C++ 中return *this和return this的區(qū)別

    return *this返回的是當(dāng)前對(duì)象的克隆或者本身,return this返回當(dāng)前對(duì)象的地址,下面通過(guò)本文給大家介紹C/C++ 中return *this和return this的區(qū)別,感興趣的朋友一起看看吧
    2019-10-10
  • C語(yǔ)言泛型編程實(shí)例教程

    C語(yǔ)言泛型編程實(shí)例教程

    這篇文章主要介紹了C語(yǔ)言泛型編程,針對(duì)泛型的用法做了深入淺出的實(shí)例介紹,是C程序設(shè)計(jì)中非常實(shí)用的技巧,需要的朋友可以參考下
    2014-09-09
  • C++實(shí)現(xiàn)關(guān)系與關(guān)系矩陣的代碼詳解

    C++實(shí)現(xiàn)關(guān)系與關(guān)系矩陣的代碼詳解

    這篇文章主要介紹了C++實(shí)現(xiàn)關(guān)系與關(guān)系矩陣,功能實(shí)現(xiàn)包括關(guān)系的矩陣表示,關(guān)系的性質(zhì)判斷及關(guān)系的合成,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C語(yǔ)言實(shí)現(xiàn)BMP圖像的讀寫(xiě)功能

    C語(yǔ)言實(shí)現(xiàn)BMP圖像的讀寫(xiě)功能

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)BMP圖像的讀寫(xiě)功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • C++中雙冒號(hào)::用法案例詳解

    C++中雙冒號(hào)::用法案例詳解

    這篇文章主要介紹了C++中雙冒號(hào)::用法案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Unity編輯器下重啟的方法

    Unity編輯器下重啟的方法

    這篇文章主要介紹了Unity編輯器下重啟的方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10

最新評(píng)論