_c++11

在这里插入图片描述

嗨喽大家好呀,今天阿鑫给大家带来的是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.xdnf.cn/news/1557296.html

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

相关文章

气膜体育馆:解决场地困境的新选择—轻空间

北京市近日出台了关于规范和加强新建充气膜体育建筑的指导意见&#xff0c;旨在有效解决区域体育配套不足的问题。这一政策的出台&#xff0c;不仅为全民健身打造了新的载体&#xff0c;也为校园体育设施建设指明了方向。 满足日益增长的健身需求 随着人们健康意识的提升&#…

Skyeye 云智能制造 v3.14.8 发布,ERP 商城 + AI

Skyeye 云智能制造&#xff0c;采用 Springboot winUI 的低代码平台、移动端采用 UNI-APP。包含 30 多个应用模块、50 多种电子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公告、问卷、报表…

openmmlab使用系列(二):图像超分辨率重构

文章目录 前言一、图像超分辨率重构简介二、mmmagic实现图像超分 前言 超分辨率重构技术&#xff0c;作为计算机视觉领域的一项重要研究课题&#xff0c;近年来受到了广泛关注。随着科技的飞速发展&#xff0c;人们对图像质量的要求越来越高&#xff0c;尤其是在智能手机、监控…

SpringBoot3实战:实现接口签名验证

有时候我们要把自己的服务暴露给第三方去调用&#xff0c;为了防止接口不被授权访问&#xff0c;我们一般采用接口签名的方式去保护接口。 接下来松哥和大家聊一聊这个话题。 一 场景分析 什么时候需要接口签名&#xff1f; 接口签名是一种重要的安全机制&#xff0c;用于确…

JAVA基础: synchronized 和 lock的区别、synchronized锁机制与升级

1 synchronized 和 lock的区别 synchronized是一个关键字&#xff0c; lock是一个接口&#xff0c;实际使用的是实现类 synchronized通过触发的是系统级别的锁机制&#xff0c; lock是API级别的锁机制 synchronized自动获得锁&#xff0c;自动释放锁。 lock需要通过方法获得锁…

[oeasy]python036_数据类型有什么用_type_类型_int_str_查看帮助

回忆上次内容 ord(c)和chr(i) 这是俩函数 这俩函数是一对 相反相成的⚖️ ord 通过 字符 找到对应的 序号chr 通过 序号 找到对应的 字符 为什么ord后面括弧里的参数 一定 要加引号不加不行 而chr后面括弧里的参数 又一定 不加引号加了不行呢&#xff1f;&#x1f914; TypeErr…

强基计划与少儿编程有什么关系?

近年来&#xff0c;编程教育逐渐在基础教育中崭露头角&#xff0c;成为培养孩子逻辑思维、创新能力和解决问题能力的重要手段。而2020年推出的强基计划则是一项面向高考生的特殊招生计划&#xff0c;旨在为基础学科&#xff08;如数学、物理、化学、生物、历史、哲学等&#xf…

MySQL 删除数据库

使用 mysqladmin 删除数据库 使用普通用户登陆MySQL服务器&#xff0c;你可能需要特定的权限来创建或者删除 MySQL 数据库。 所以我们这边使用root用户登录&#xff0c;root用户拥有最高权限&#xff0c;可以使用 MySQL mysqladmin 命令来删除数据库。 在删除数据库过程中&a…

双向数据库迁移工具:轻松实现 MySQL 与 SQLite 数据互导

项目概述与作用 该项目的核心是实现 MySQL 和 SQLite 两种数据库之间的数据迁移工具。它能够轻松地将 MySQL 数据库中的数据导出为 SQLite 数据库文件&#xff0c;反过来也可以将 SQLite 数据库中的数据上传到 MySQL 数据库中。这个双向迁移工具非常适用于&#xff1a; 数据库备…

51c自动驾驶~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/11491137 #BEVWorld BEV潜在空间构建多模态世界模型&#xff0c;全面理解自动驾驶~一、引言 世界模型建模了有关环境的知识&#xff0c;其可以通过给定的条件对未来进行合理的想象。未来想象要求世界模型具有物理规律的理解…

利用 OpenAI 和 Python 预测股市行情

作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话: 本文介绍了如何利用 OpenAI 和 Python 进行股市情绪预测。主要通过使用 EODHD 提供的股市和金融新闻 API 来提取新闻数据,并利用 LangChain 和 OpenAI 的大型语言模型进行情感分析。 一、综述 …

如何在电脑上启动两个微信实例

前言 有时候&#xff0c;我们需要在电脑端登陆两个微信&#xff0c;来处理不同的事情&#xff0c;之前快速双击微信图标即可打开多个微信&#xff0c;最近发现不是太好使&#xff0c;所以今天介绍一种使用window命令启动两个微信的方法。 步骤 1、找到微信的安装目录&#x…

js逆向--某招标公告公示搜索引擎DES解密

js逆向--某招标公告公示搜索引擎DES解密 一、寻找数据接口二、寻找解密入口三、编写代码一、寻找数据接口 打开网页,在搜索框中输入关键词python。 试图通过按F12或者右键打开开发者工具,发现均没有反应。这时需要点击浏览器右上角的三个点,然后点击更多工具–开发者工具,…

增强分析:新时代的数据洞察工具

随着数据科学和人工智能的迅猛发展&#xff0c;分析数据的方式也发生了显著的变化。增强分析&#xff08;Augmented Analytics&#xff09;是近年来涌现出的新概念&#xff0c;它将人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;和自然语言处理&…

华为OD机试 - 实力差距最小总和(Java 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

SpringBoot 集成 Redis

一&#xff1a;SpringBoot 集成 Redis ①Redis是一个 NoSQL&#xff08;not only&#xff09;数据库&#xff0c; 常作用缓存 Cache 使用。 ②Redis是一个中间件、是一个独立的服务器&#xff1b;常用的数据类型&#xff1a; string , hash ,set ,zset , list ③通过Redis客…

【2024年持续更新】国内ChatGPT-4中文镜像网站整理

目录 一、什么是ChatGPT镜像站&#xff1f; 二、GPT工具跟国内AI大模型整理 三、国内大模型与ChatGPT的区别 四、ChatGPT能做什么&#xff1f; 五、ChatGPT提示词教学 一、什么是ChatGPT镜像站&#xff1f; 镜像网站是指将原始网站的内容复制并放置在另一服务器上的网站。…

在 Hugging Face MTEB 排行榜上比较 ELSER 的检索相关性

作者&#xff1a;来自 Elastic Aris Papadopoulos 及 Serena Chou 本博客对 ELSER 在 Hugging Face MTEB 排行榜上的检索相关性进行了比较。 在 Hugging Face MTEB 排行榜上比较 ELSER 的检索相关性 ELSER&#xff08;Elastic Learned Sparse EncodeR&#xff09;是 Elastic …

Linux TFTP服务器搭建

话得多说 先水一波字 TFTP&#xff08;Trivial File Transfer Protocol&#xff09;是一种简单的文件传输协议。它用于在计算机网络中传输文件&#xff0c;特别适用于在网络设备&#xff08;如开发板和Linux系统下&#xff09;代码调试等操作。TFTP使用UDP&#xff08;User Da…

多模态大语言模型(MLLM)-Blip2深度解读

前言 Blip2是一个多模态大语言模型&#xff0c;因其提出时间较早&#xff08;2023年&#xff09;&#xff0c;且效果较好&#xff0c;很快成为一个标杆性工作。Blip2中提出的Q-former也成为衔接多模态和文本的重要桥梁。 Blip2发表时间是2023年&#xff0c;现在引用已经3288了…