一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C++11中列表初始化機制的概念與實例詳解

C++11中列表初始化機制的概念與實例詳解

2022-02-20 14:48ChlorineCL C/C++

在我們實際編程中,我們經常會碰到變量初始化的問題,對于不同的變量初始化的手段多種多樣,下面這篇文章主要給大家介紹了關于C++11中列表初始化機制的相關資料,需要的朋友可以參考下

概述

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

C++11以前只能使用列表初始化來初始化內置類型數組和POD類型對象,C++11中列表初始化可以用于初始化任何類型對象

  • POD(plain old data)類型:僅由內置類型變量構成且不含指針的類,簡單來說是可以直接使用memcpy復制的對象
  • 聚合體(aggregate):聚合體一定是POD類型
    • 無自定義構造函數
    • 無私有或保護的非靜態(tài)數據成員(靜態(tài)成員與單獨對象無關,故不影響初始化)
    • 無基類
    • 無虛函數
    • 無類內已經初始化的非靜態(tài)數據成員

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

列表初始化:用{}進行初始化的方式

初始化列表:構造函數體前對對象成員直接進行初始化的列表

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

 

實現機制詳解

對內置類型對象、POD對象和類對象的列表初始化實現細節(jié)是不同的

POD類型的列表初始化

  • 此處POD類型包括:內置類型、聚合體類
  • 內置類型數組按照順序初始化
    • C++11標準中列表初始化會防止可能導致潛在信息丟失的類型縮小(即不能像賦值一樣將大類型如int隱式轉換成小類型如char)
  • 聚合體類按照成員定義順序依次初始化

含有構造函數的類的列表初始化(C++11)

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

列表初始化用于函數返回值

  • 在返回值類型為對象(不能是對象的引用)的函數中可以返回{}的列表初始化
  • {}返回值的實際類型為initiallizer list(但不能聲明為std::initializer_list),相當于返回構造函數的表達式,因此類型不能是對象的引用

引入std::initializer_list

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

 

代碼驗證

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;
}

以下為運行截圖

C++11中列表初始化機制的概念與實例詳解

列表初始化測試

添加initializer_list為參數的構造函數后

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;
}

以下為運行截圖

C++11中列表初始化機制的概念與實例詳解
添加init_list后測試截圖

由此可見所有列表初始化都調用了含有initializer_list為參數的構造函數,證實了列表初始化是基于隱式轉換并以initializer_list為底層實現的構想

 

應用

  • 在聲明時直接初始化堆上分配的對象(數組)
    • 類:可以顯式指定使用的構造函數(默認會執(zhí)行無參數的構造函數)
    • 內置類型:可以在分配時直接指定值
  • 在函數返回對象時避免自動存儲期對象銷毀的問題
  • 手動調用std::initializer_list實現可變參數初始化

 

列表初始化防止類型收窄

C++11的列表初始化還有一個額外的功能就是可以防止類型收窄,也就是C++98/03中的隱式類型轉換,將范圍大的轉換為范圍小的表示,在C++98/03中類型收窄并不會編譯出錯,而在C++11中,使用列表初始化的類型收窄編譯將會報錯:

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

 

總結

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

初始化類對象時,通過()調用構造函數的地方都可以完全等價地用{}代替

={}不會生成臨時對象再拷貝初始化

到此這篇關于C++11中列表初始化機制的文章就介紹到這了,更多相關C++11列表初始化機制內容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/ChlorineCL/article/details/121211868

延伸 · 閱讀

精彩推薦
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++c++ 單線程實現同時監(jiān)聽多個端口

    c++ 單線程實現同時監(jiān)聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監(jiān)聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
主站蜘蛛池模板: 日本卡一卡2卡3卡4精品卡无人区 | 亚洲国产一区二区三区青草影视 | 国产1区2区在线观看 | 美人的淫事[纯hh] | 国产精品区一区二区免费 | 美女任你摸 | 啊啊啊好大好爽视频 | 热九九精品 | 日本tube24xxxxx | 四虎库 | 亚洲成色WWW久久网站夜月 | ass韩国美女人体pics | 国产午夜亚洲精品不卡 | 黑人异族日本人hd | 成人1234| 天仙tv微福视频 | 久久草香蕉频线观 | 欧美色精品天天在线观看视频 | 日韩精品亚洲一级在线观看 | 国产精品免费视频能看 | 亚洲AV蜜桃永久无码精品红樱桃 | 成人福利在线播放 | 久久这里只有精品无码3D | 校园肉文高h | 毛片免| 水野朝阳厨房系列在线观看 | 50度灰破解版v5.7.0 | 嫩草影院永久一二三入口 | 国产精品免费视频一区一 | 乌克兰粉嫩摘花第一次 | 亚洲a视频在线观看 | 成人国产精品一级毛片视频 | 日本老妇成熟 | 日本一二线不卡在线观看 | 爸爸的宝贝小说全文在线阅读 | 日韩成a人片在线观看日本 日韩不卡一区二区 | 成人免费观看在线视频 | 国产盗摄女厕美女嘘嘘 | 成人网18免费网站 | 亚洲丰满女人ass硕大 | s0e一923春菜花在线播放 |