_c++11

news2024/11/24 22:40:34

在这里插入图片描述

嗨喽大家好呀,今天阿鑫给大家带来的是c++进阶——c++11的内容,好久不见啦,下面让我们进入本节博客的内容吧!

_c++11

  1. 统一的列表初始化
  2. 右值引用
  3. 可变模板参数(了解,不常接触)
  4. lambda表达式
  5. function和bind包装器

1. 统一的列表初始化

1.1{}初始化

C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自
定义的类型,使用初始化列表时,可添加等号(=),也可不添加。

struct Point
{
int _x;
int _y;
};
int main()
{
int x1 = 1;
int x2{ 2 };
int array1[]{ 1, 2, 3, 4, 5 };
int array2[5]{ 0 };
Point p{ 1, 2 };
// C++11中列表初始化也可以适用于new表达式中
int* pa = new int[4]{ 0 };
return 0;
}

创建对象时也可以使用列表初始化方式调用构造函数初始化

class Date
{
public:
Date(int year, int month, int day)
:_year(year)
,_month(month)
,_day(day)
{
cout << "Date(int year, int month, int day)" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2022, 1, 1); // old style
// C++11支持的列表初始化,这里会调用构造函数初始化
Date d2{ 2022, 1, 2 };
Date d3 = { 2022, 1, 3 };
return 0;
}

1.2 std::initializer_list

std::initializer_list使用场景:
std::initializer_list一般是作为构造函数的参数,C++11对STL中的不少容器就增加
std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。也可以作为operator=的参数,这样就可以用大括号赋值。

namespace bit
{
template<class T>
class vector {
public:
  typedef T* iterator;
  vector(initializer_list<T> l)
  {
    _start = new T[l.size()];
    _finish = _start + l.size();
    _endofstorage = _start + l.size();
    iterator vit = _start;
    typename initializer_list<T>::iterator lit = l.begin();
    while (lit != l.end())
    {
      *vit++ = *lit++;
    }
    //for (auto e : l)
    //  *vit++ = e;
  }
  vector<T>& operator=(initializer_list<T> l) {
    vector<T> tmp(l);
    std::swap(_start, tmp._start);
    std::swap(_finish, tmp._finish);
    std::swap(_endofstorage, tmp._endofstorage);
    return *this;
  }
private:
  iterator _start;
  iterator _finish;
  iterator _endofstorage;
};
}

在这里插入图片描述

struct Goods
{
	string _name; 
	double _price; // 价格
	int _evaluate; // 评价
	Goods(const char* str = "", double price = 0, int evaluate = 0)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{}
};

zj::vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2,3 }, { "菠萝", 1.5, 4  }};

在这里插入图片描述
initializer_list的原理和数组相似,都是在在栈上创建一个数组,然后将值进行拷贝

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.右值引用

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

匿名对象的生命周期通常局限于它们被创建和使用的上下文。然而,在特定情况下(如作为函数返回值或作为const引用的初始化器),它们的生命周期可能会被延长。但是,开发者应该始终注意避免依赖于这种延长的生命周期,因为这可能会导致难以发现的错误和未定义行为。

左值引用和右值引用的底层
从汇编角度看,左值引用和右值引用没有区别
在这里插入图片描述

//移动构造,临时创建的对象,用完就要消亡
	string::string(string&& s)
		: _str(nullptr)
	    ,_size(0)
	    ,_capacity(0)
	{
		swap(s);
		std::cout << "string(string&& s) -- 移动拷贝" << std::endl; 
	}

场景1.传值返回

移动构造出现后加上编译器的特殊处理,相当于传值返回没有拷贝了
返回值的类型由中间生成的临时变量决定
当一个匿名对象或临时对象被引用时,会延长它的生命周期
在这里插入图片描述
移动赋值用来解决如下情景
在这里插入图片描述
在这里插入图片描述

	string& string::operator=(string&& s)
	{
		cout << "string::string(string&& s)---移动赋值" << endl;
		swap(s);
		return *this;
	}

场景2.push_back等接口中

在这里插入图片描述
注意点1:只有const T& x的话,只会调用深拷贝不会调用移动拷贝,所以需要两套push_back,move可以对const使用,而为什么不能依靠一个const左(const一旦沾上就不能放下),最终构造节点时,不可能将const左值传给右值。

const右值必须用const右值引用来接收
右值用右值引用或者const左值引用

注意点2:右值引用本身是左值
只有右值会调用移动拷贝,右值(语言层面上不支持修改,因为想要将右值的资源进行转移,我们可以调用移动拷贝对右值进行修改),const不支持修改。
被引用或者move后不会影响原来值的性质,右值引用本身和const引用本身都是左值,右值引用和const引用可以支持move。
在这里插入图片描述
万能引用—完美转发
在这里插入图片描述

在这里插入图片描述

1.当你自己没有实现移动构造函数,并且没有实现析构函数,拷贝构造,拷贝赋值构造之中任意一个(“三位一体”),编译器就会自动生成一个默认移动构造函数(对于内置类型值拷贝,对于自定义类型成员有移动构造调用移动构造,否则调用拷贝构造)
2.没有实现析构,拷贝构造需要默认的移动构造自定义成员调用自定义移动构造的原因:对于对象来说(只要用默认的析构,值拷贝)都不需要显示实现移动构造,但为了避免对象内的自定义类型成员(比如string类型)实现了移动构造,所以需要一个默认的移动构造。
3.如果有析构就不会生成默认移动构造的原因:(1)因为如果有析构函数或者拷贝构造就说明这个自己维护了一块空间,内置类型不能只进行简单的值拷贝,所以编译器不会生成默认的移动构造,编译器认为用户想自己实现移动构造, (2)如果用户自己不写,编译器也不会生成(因为已经违反了默认移动构造的规则),编译器认为用户就是自己单纯不想调用移动构造或者不了解移动构造。
4.简而言之,自己没有资源需要管理,不代表成员变量没有成员需要管理。

在这里插入图片描述
在这里插入图片描述

3.可变模板参数(了解,不常接触)

节省了很多个模板
参数类型和个数都可变
在这里插入图片描述
emplace_back整体而言更高效

在这里插入图片描述
可以不用像之前一样传pair对象,将构造pair的参数包往下传,但是只能传一个复合对象(类似pair)
在这里插入图片描述

在这里插入图片描述

4.lambda表达式

lambda表达式实际是一种匿名函数
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

此处的&a与之前所认识的&a,int&a的概念有所不同,此处的&a表示的是引用。

在这里插入图片描述
在这里插入图片描述
捕捉列表的对象时成员变量存在在lambda类对象中,捕捉的本质是构造函数的初始化参数
编译器的底层没有lambda,当我们定义一个lambda表达式时,编译器吧会自动生成一个类,在该类中重载operator()。

5.function和bind包装器

5.1function包装器

function是要接收一个可调用的对象的,将接收的可调用对象作为成员变量,内部重载了operator(),进行调用时就是对接收的可调用对象的回调。
可调用对象包括:函数指针对象,仿函数对象,lambda对象

在这里插入图片描述

#include <functional>  
#include <iostream>  
  
class Functor {  
public:  
    int operator()(int a, int b) const {  
        return a + b; // 假设这是Functor的一个简单实现  
    }  
    // 可能还需要一个转换到 std::function<int(int, int)> 的构造函数或转换操作符  
    // 但在这个例子中,我们不需要显式定义它,因为lambda和std::bind等可以隐式转换  
};  
  
int main() {  
    // f2 包装了一个 Functor 类的临时对象(或者更准确地说,是 Functor 的一个实例)  
    std::function<int(int, int)> f2 = Functor(); // 这里 Functor() 创建了一个临时对象  
  
    // 现在 f2 可以像函数一样被调用  
    std::cout << f2(2, 3) << std::endl; // 输出 5  
  
    // 关于 f3,您的原始代码有语法错误,但假设您想要的是这样的:  
    // 一个接受两个参数的函数,第一个参数是int,第二个参数是另一个函数(即f2的类型)  
    std::function<int(int, std::function<int(int, int)>)> f3 =   
        [](int x, std::function<int(int, int)> func) {  
            return func(x, x + 1); // 假设我们总是对第二个参数使用 x+1  
        };  
  
    // 使用 f3,其中第二个参数是 f2  
    std::cout << f3(4, f2) << std::endl; // 输出 9,因为 f2(4, 5) = 9  
  
    return 0;  
}

注意:本质看成对函数的回调
普通成员函数的调用需要对象或者对象的指针。
普通成员函数的函数指针前要加&

对于分别传this对象和this指针的解释是,本质上不是直接将plus和plus*直接传给函数plusd的,而是通过this对象或者this指针去调用封装的函数

在这里插入图片描述

5.2 bind包装器

在这里插入图片描述
在这里插入图片描述
placeholders::_1表示可调用对象的第一个实参,对应sub1的第一个参数
sub1的参数代表实参
在这里插入图片描述

注意: _1代表的是第一个实参
_2代表的是第二个实参

在这里插入图片描述
在这里插入图片描述

bind可以用来解决function包装非静态的成员函数问题,bind本质返回的是一个仿函数对象
绑定函数调用的第一个参数来解决每次调用非静态成员函数都需要传this或者this指针的情况。
在这里插入图片描述

5.3function和bind的配合使用

#include<functional>
#include<iostream>
using namespace std;
int main()
{

	auto func1 = [](double rate, double money, int year)->double {
		double ret = money;
		for (int i = 0; i < year; i++)
		{
			ret += ret * rate;
		}
		return ret-money;
		};
	//三年期
	function<double(double)> f3_1_5 = bind(func1, 0.015, placeholders::_1, 3);
	function<double(double)> f3_2_5 = bind(func1, 0.025, placeholders::_1, 3);
	function<double(double)> f5_1_5 = bind(func1, 0.015, placeholders::_1, 5);
	function<double(double)> f10_3_5 = bind(func1, 0.035, placeholders::_1, 10);
	cout << f3_1_5(1000000) << endl;
	cout << f3_2_5(1000000) << endl;
	cout << f5_1_5(1000000) << endl;
	cout<<f10_3_5(1000000)<<endl;

	return 0;
}

function和bind相互配合可以完成类似多态的功能。

好啦,今天我们的学习就到这里哦,本节课内容还是有点难度的,希望大家能够好好吸收理解,期待我们的下一次再见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2196940.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaWeb 15.详解Servlet及其源码

所有受过的委屈&#xff0c;都在提醒你 要好好争气。 —— 24.10.7 一、Servlet简介 1.动态资源和静态资源 静态资源 无需在程序运行时通过代码运行生成的资源&#xff0c;在程序运行之前就写好的资源&#xff0c;例如&#xff1a;html、css、js、img、音频文件和视频文件 …

职场秘籍:面试加薪,竟然拥有不同的技巧!

假如你是一位测试主管&#xff0c;去评价一名测试工程师是否优秀&#xff0c;那么你将如何去判断呢&#xff1f;你最看重的是哪方面的能力呢&#xff1f; 对于这个问题&#xff0c;是不能一概而论的&#xff0c;要分为两种情况&#xff0c;情况不同&#xff0c;答案一定是不同…

高校新生报道管理系统使用SpringBootSSM框架开发

&#xff01;&#xff01;&#xff01;页面底部,文章结尾,加我好友,获取计算机毕设开发资料 目录 一、引言 二、相关技术介绍 三、系统需求分析 四、系统设计 五、关键技术实现 六、测试与优化 七、总结与展望 一、引言 当前高校新生报到过程中存在许多问题&#xff0c;…

从0到1:用Python构建你人生中的第一个人工智能AI模型

文章目录 摘要引言数据预处理&#xff1a;为模型打下坚实基础数据预处理的步骤Python示例代码说明&#xff1a;注意事项&#xff1a; 模型建立&#xff1a;选择合适的模型神经网络示例代码说明&#xff1a; 模型训练与测试训练示例代码说明&#xff1a; 解读模型结果性能指标 深…

原生小程序开发|小程序卡片(Widget) 开发指南

开发 Widget 代表应用的一个小程序卡片&#xff0c;负责小程序卡片的展示和交互。 小程序卡片(Widget) 的开发在智能小程序的基础上增加一个目录即可&#xff0c;用于存放小程序卡片(Widget)的代码。并在 project.tuya.json 中增加一个声明。 创建小程序卡片(Widget)项目 在 …

九、Drf序列化器

九、序列化器 9.1序列化 从数据库取QuerySet或数据对象转换成JSON 9.1.1序列化器的简易使用 #新建一张部门表 class Depart(models.Model):title=models.CharField(verbose_name=部门,max_length=32)order=models.IntegerField(verbose_name=顺序)count=models.IntegerFiel…

vscode中安装python的包

首先需要调出命令行。然后运行代码&#xff0c;找到你所需要的环境。 PS C:\Users\Administrator\AppData\Local\ESRI\conda\envs\arcgispro-env> conda env list # conda environments: #C:\ProgramData\Anaconda3 base * C:\Users\Administrator\.con…

【无人机设计与控制】无人机三维路径规划,对比蚁群算法,ACO_Astar_RRT算法

摘要 本文探讨了三种不同的无人机三维路径规划算法&#xff0c;即蚁群算法&#xff08;ACO&#xff09;、A算法&#xff08;Astar&#xff09;以及快速随机树算法&#xff08;RRT&#xff09;。通过仿真实验对比了各算法在不同环境下的性能&#xff0c;包括路径长度、计算效率…

软考越来越难了,2024年软考究竟还值不值得考?

最近不少同学沟通&#xff0c;聊到软考现在越来越难了&#xff0c;考了两三次都没过&#xff0c;也有不少新同学咨询软考考试的一些福利政策&#xff0c;投入大量的物力&#xff0c;财力&#xff0c;精力&#xff0c;那么到底软考值不值得考呢&#xff1f; 01 / 关于软考 软考…

【FlagScale】异构算力混合训练方案

背景以及必要性 算力需求的高峰&#xff1a;随着人工智能&#xff08;AI&#xff09;和生成内容&#xff08;AIGC&#xff09;的发展&#xff0c;对计算资源的需求急剧增加。尤其是参数规模达到数百亿的大模型训练&#xff0c;需要大量的计算资源。 算力市场供应紧张&#xff…

一键拯救废片!3个在线教程,实现光线重塑、表情迁移、模糊图像修复

每逢国庆「黄金周」&#xff0c;都是旅游业的高光时刻。根据研判&#xff0c;今年国庆假期全社会跨区域人员流动量将达到 19.4 亿人次&#xff0c;平均每天 2.77 亿人次。 与旅游业同步增长的还有摄影行业&#xff0c;旅拍带动的妆造、服饰租赁等相关环节发展火热&#xff0c;…

Linux安装Redis7.40

一、环境检查 1.1 查看是否已经安装了Redis应用 ps -ef |grep redis或者 whereis redis1.2 若已经安装了redis应用或者有遗留的Redis文件&#xff0c;进行移除或者启动即可。 二、下载&安装 2.1 找到对应的安装包资源&#xff0c;使用wget命令下载&#xff0c;这里安装…

小众交友软件有哪些?小众交友APP排行榜前十名推荐

在网络的广袤天地中&#xff0c;小众交友软件如隐藏的宝藏&#xff0c;散发着独特魅力。它们为人们提供别样的社交舞台&#xff0c;让孤独的灵魂有处可栖。今天&#xff0c;就让我们一同探寻那些小众交友软件的奇妙世界。 1. 咕哇找搭子小程序&#xff1a;这是一个实名制的找搭…

想要加密电脑?盘点2024年企业常用的10款电脑文件加密软件

在企业数据安全的时代背景下&#xff0c;文件加密已经成为保护企业核心信息、应对网络安全威胁的关键举措。无论是保护机密的商业数据&#xff0c;还是遵守数据隐私合规性要求&#xff0c;企业对文件加密软件的需求日益增长。本文将盘点2024年企业常用的10款电脑文件加密软件&a…

【Java 问题】基础——序列化

接上文 序列化 45.什么是序列化&#xff1f;什么是反序列化&#xff1f;46.说说有几种序列化方式&#xff1f; 45.什么是序列化&#xff1f;什么是反序列化&#xff1f; 什么是序列化&#xff0c;序列化就是把Java对象转为二进制流&#xff0c;方便存储和传输。 所以反序列化…

SOA是什么

SOA SOA 即 Service-Oriented Architecture&#xff08;面向服务的架构&#xff09;。 一、定义 SOA 是一种软件设计方法和架构理念&#xff0c;它将应用程序的不同功能单元&#xff08;称为服务&#xff09;通过定义良好的接口和契约联系起来。这些服务可以独立部署、独立运…

【JavaEE初阶】深入理解不同锁的意义,synchronized的加锁过程理解以及CAS的原子性实现(面试经典题);

前言 &#x1f31f;&#x1f31f;本期讲解关于锁的相关知识了解&#xff0c;这里涉及到高频面试题哦~~~ &#x1f308;上期博客在这里&#xff1a;【JavaEE初阶】深入理解线程池的概念以及Java标准库提供的方法参数分析-CSDN博客 &#x1f308;感兴趣的小伙伴看一看小编主页&am…

(笔记)第三期书生·浦语大模型实战营(十一卷王场)–书生基础岛第6关---OpenCompass 评测 InternLM-1.8B 实践

学员闯关手册&#xff1a;https://aicarrier.feishu.cn/wiki/ZcgkwqteZi9s4ZkYr0Gcayg1n1g?open_in_browsertrue 课程视频&#xff1a;https://www.bilibili.com/video/BV1RM4m1279j/ 课程文档&#xff1a; https://github.com/InternLM/Tutorial/blob/camp3/docs/L1/OpenComp…

嵌入式设备硬件和软件安全设计

1. 引言 哪个领域的网络安全实施记录最差&#xff1f; 既不是 PKI/数字证书&#xff0c;也不是 密钥管理&#xff0c;也不是 OAuth。很可能是嵌入式设备和物联网 领域。 总的来说&#xff0c;这似乎是一个梦想&#xff0c;但如果可设计出“设计安全”的系统&#xff0c;而不…

转行大模型开发,能不能挽救职业生涯?

大模型算是当之无愧最火的一个方向了&#xff0c;算是新时代的风口。有小伙伴觉得&#xff0c;既然是新领域、新方向&#xff0c;那么&#xff0c;人才需求肯定比较大&#xff0c;相应的人才缺乏&#xff0c;竞争也会更少&#xff0c;那转行去做大模型是不是一个更好的选择呢&a…