C++11中列表初始化机制的概念是什么

技术C++11中列表初始化机制的概念是什么本篇内容介绍了“C++11中列表初始化机制的概念是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔

本文介绍了“C 11中列表初始化机制的概念是什么”的知识。很多人在实际案例操作中都会遇到这样的困难。接下来,让边肖带领大家学习如何应对这些情况!希望大家认真阅读,学点东西!

00-1010定义:列表初始化是C 11推出的新标准,旨在统一初始化方法

以前,C 11只能使用列表初始化来初始化内置类型数组和POD类型对象。C 11中的列表初始化可以用来初始化任何类型的对象。

POD(普通旧数据)类型:只由内置类型变量组成的类,没有指针。简单来说,就是一个可以被memcpy直接复制的对象。

聚合:聚合必须是POD类型

没有自定义构造函数

无私或受保护的非静态数据成员(静态成员与单个对象无关,因此不影响初始化)

没有基类

没有虚函数

类中没有初始化的非静态数据成员。

注意:区分列表初始化和列表初始化。

List:用{}初始化的方法。

初始化列表:直接在构造函数体之前初始化的对象成员列表。

Initializer_list:一个用于未确定参数的轻量级STL容器

概述

内置类型对象、POD对象、类对象的列表初始化的实现细节不同。

00-1010这里的POD类型包括:内置型和聚合物型。

内置类型数组按顺序初始化。

在C 11标准中,列表初始化将防止可能导致潜在信息丢失的类型缩小(也就是说,像int这样的大类型不能隐式转换为像char这样的小类型,比如赋值)

类根据成员定义的顺序依次初始化。

00-1010由{}初始化与由()初始化是一致的(即所有由()调用构造函数的地方都可以等价地完全由{}替换)。两者都是通过用括号中的值调用相应的构造函数直接初始化对象,不会作为临时对象复制。

={}和{}是等价语法(即是否添加=对初始化行为没有影响),两者都不会调用copy运算符或copy构造函数。

与内置类型的列表初始化一致,C 11的列表初始化只能用于初始化,不能用于初始化对象的赋值

实际机制猜想:传递的实际参数是initializer_list类型,调用是通过匹配重载函数来实现的[这个过程我不知道怎么验证,求大答案]

00-1010在返回值类型为对象(不是对对象的引用)的函数中,可以返回{}的列表初始化。

{}返回值的实际类型是initiallizer list(但不能声明为STD STD : initializer _ list),相当于返回构造函数的表达式,因此该类型不能是对象的引用。

00-1010 initializer_list是一个轻量级的STL模板,在头文件initializer_list中声明,在命名空间std中定义。

任何STL容器都具有与长度不确定的数组相同的初始化能力,并且可以填充任意数量的相同类型的数据,因此使用STL容器很容易为固定类型的类赋值。

Initializer_list是一个轻量级模板,可以接受任意长度的同类型数据,即可变长度参数。同时,作为一个STL容器,它具有STL容器的共同特点(比如迭代器)。

只有三个成员接口:begin() end() size()

它只能作为一个整体进行初始化和赋值,迭代器遍历的数据只能读取,不能针对单个数据进行修复。

  • 所有{}对象都是隐式创建的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;
    }

    列表初始化测试

    添加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为底层实现的构想

    应用

    • 在声明时直接初始化堆上分配的对象(数组)

      • 类:可以显式指定使用的构造函数(默认会执行无参数的构造函数)

      • 内置类型:可以在分配时直接指定值

    • 在函数返回对象时避免自动存储期对象销毁的问题

    • 手动调用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中列表初始化机制的概念是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

    内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/77883.html

    (0)

    相关推荐

    • JQuery如何删除UL最后一个li

      技术JQuery如何删除UL最后一个li本篇内容主要讲解“JQuery如何删除UL最后一个li”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JQuery如何删除UL最后一个l

      攻略 2021年11月15日
    • 我的世界天堂门怎么做手机版,《我的世界》天空之门怎么做

      技术我的世界天堂门怎么做手机版,《我的世界》天空之门怎么做在游戏原版只有地狱,也就是下界,但是以太MOD里有个天堂门,可以用萤石代替黑曜石像搭地狱门那样搭一个门,然后用金锭和燧石合成一个类似打火石的东西,最后像点燃地狱门

      生活 2021年10月19日
    • 怎么使用jQuery选择器

      技术怎么使用jQuery选择器本篇内容介绍了“怎么使用jQuery选择器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!先

      攻略 2021年11月18日
    • 早餐有哪些,你们那的早餐什么最好吃

      技术早餐有哪些,你们那的早餐什么最好吃我在内蒙古呼和浩特呆了12年,已经习惯内蒙的早点,内蒙的早点相对于我老家江苏来说比较粗狂,拿东北人的话来说就是基本是硬早点,如果说内蒙的早点最有特色的我给大家推荐三种我个人认为最能代

      生活 2021年10月27日
    • 第四章学习笔记,20191213兰毅达)

      技术第四章学习笔记,20191213兰毅达) 第四章学习笔记(20191213兰毅达)第四章学习笔记一、概述
      本章论述了并发编程,介绍了并行计算的概念,指出了并行计算的重要性;比较了顺序算法与并行算法以

      礼包 2021年10月28日
    • 传输层协议与路由器

      技术传输层协议与路由器 传输层协议与路由器1、 TCP协议:
      面向连接的,可靠的进程到进程通信的协议
      TCP提供全双工服务
      2、UDP协议:
      无连接的不可靠的协议
      效率高
      3、TCP报文段U R G :

      礼包 2021年12月2日