【C++】C++11新特性

目录

列表初始化

左值与右值

左值引用和右值引用 

移动构造和移动赋值

类型推导

lambda

捕捉列表 

函数对象及绑定

bind函数

包装器 

Args参数包

抛异常


列表初始化

在C++11中一切皆可用列表初始化。

用法:直接在变量名后面加上初始化列表进行初始化

class T1
{
public:Test(int x,int y):_x(x),_y(y) {}~Test() {}
private:int _x;int _y;
};struct T2
{int x;int y;
}int main()
{vector<int>a1({ 1,2,3 });//构造//等于号可有可无vector<int>a2{ 1,2,3 };vector<int>a3 = { 1,2,3 };//内置类型也可以使用列表初始化int a4 = { 1 };int a5{ 1 };//自定义类型根据其构造函数使用即可//这里实际上是:多参数的隐式类型转换T1 a6({ 1,2 });T1 a7{ 1,2 };T1 a8 = { 1,2 };T2 a9 = { 2,2 };return 0;
}

左值与右值

  • 左值:可以(&)取地址,可以对其赋值(可以出现在赋值号的左边)
  • 右值:不能(&)取地址,不可以出现在赋值号的左边

右值又有纯右值和将亡值两种,纯右值指内置类型的,而将亡值是自定义类型的。主要表现为返回值、匿名对象和临时对象。

左值引用和右值引用 

  • 左值引用相当于左值的别名,可以减少拷贝,对于函数传引用也便于修改变量。
  • 右值引用相当于右值的别名,不可修改,可以节省资源。
  • 左值引用不能给右值取别名(但const左值引用可以)
  • 右值引用不能给左值取别名(但可以给move以后的左值取别名)

注:右值引用本身也是左值  

move(左值)的结果为右值 ,数据不变。

 

移动构造和移动赋值

        这是基于右值完成的,右值的特点是很快会被系统回收内存空间的值。这时可能就存在一个右值马上要被回收,但是恰好有对象想要这个值,此时利用移动赋值/构造将这个右值的数据给该对象,就节省了一次回收和创造的开销。

        秉承着反正你也要被回收了,还不如拿来吧你的原则,移动构造/赋值就诞生了。

 

万能引用

在函数模板中,像下图的引用被称为万能引用,可以接收左值也可以接收右值。

 

类型推导

  • decltype 关键字:用于推导表达式的类型
  • auto 关键字:允许编译器自动推导变量的类型

 用法:

  • decltype(变量名)   推导成与该变量名一样的类型。
  • auto 直接使用,会自动推导成赋值的类型。(但必须初始化)
int main()
{int x = 1;int y = 1;decltype(x) a = x + y;cout << typeid(a).name() << endl;cout << "a:" << a << endl;auto b = x + y;cout << typeid(b).name() << endl;cout << "b:" << b << endl;return 0;
}

 

 不建议滥用,可能会增加维护难度,例如查看返回值类型困难的问题。

auto A()
{return 1;
}
auto B()
{return A();
}auto C()
{return B();
}int main()
{auto a = C();return 0;
}

lambda

lambda是一种定义匿名函数对象的方法。

  • 语法:[捕捉列表] (参数列表) ->返回类型{ 函数体 }

 以add函数为例:

int main()
{auto add = [](int x, int y)->int {return x + y; };cout << add(2, 3) << endl;return 0;
}

 

捕捉列表 

捕获列表:用于指定 Lambda表达式可以访问的外部变量。

捕获分为按值捕获和引用捕获两大类,引用捕获的变量可以修改,但按值捕获的不行。其中又分为全部捕获和指定地去捕获。

int main()
{int x = 10;int y = 10;//值捕获auto add1 = [x](int y)->int {return x + y; };cout << "add1(3) = " << add1(3) << endl;cout << " x = " << x << endl;
//-------------------------------------------------//引用捕获auto add2 = [&x](int y)->int {x = 20;return x + y; };cout << "add2(3) = " << add2(3) << endl;cout<<" x = " << x << endl;
//-------------------------------------------------//全(引用)捕获auto add3 = [&]()->int {return x + y; };cout << "add3() = " << add3() << endl;cout << " x = " << x << endl;
//-------------------------------------------------//全(按值)捕获auto add4 = [=]()->int {return x + y; };cout << "add4() = " << add4() << endl;cout << " x = " << x << endl;return 0;
}

 

除此之外还能混用,例如:

int main()
{int x = 10;int y = 10;//x进行引用捕获,其余使用按值捕获auto add1 = [=,&x]()->int {return x + y; };return 0;
}

函数对象及绑定

bind函数

头文件:<functional>

使用方法:bind(函数名,...)   ...为要绑定的参数

//打印名字,年龄,编号
void Printf(string name, int age, int number)
{	cout << name << " " << age << " " << number << endl;
}int main()
{auto P1 = ::bind(Printf, "张三", std::placeholders::_1, std::placeholders::_2);//第一个参数绑定了“张三”所以不用再传入P1(20, 5);return 0;
}

 

同理可以有: 

int main()
{//全绑定auto P2 = ::bind(Printf, "张三", 20, 5);P2();//age绑定20,_1占位符对应name,_2占位符对应numberauto P3 = ::bind(Printf, std::placeholders::_1, 20, std::placeholders::_2);P3("张三", 5);//number绑定5,_1占位符对应name,_2占位符对应ageauto P4 = ::bind(Printf, std::placeholders::_1, std::placeholders::_2, 5);P4("张三", 20);return 0;
}

 绑定类的成员函数时要注意,类的成员函数是要传入this指针的。所以想对成员函数进行绑定要绑定一个对象。

 

class D
{
public:D(int y, int m, int d):_year(y), _month(m), _day(d){}void PrintfDate(){cout << _year << " : " << _month << " : " << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{D t(2025,3,12);auto P1 = ::bind(&D::PrintfDate, t);auto P2 = ::bind(&D::PrintfDate, &t);P1();P2();return 0;
}

 

包装器 

        类模板 std::function 是通用多态函数封装器。std::function 的实例能存储、复制及调用任何可调用 (Callable) 目标——函数、 lambda 表达式、 bind 表达式或其他函数对象,还有指向成员函数指针和指向数据成员指针。

使用方法:function<返回值(参数类型列表)>  变量名 = 函数指针

//打印名字,年龄,编号
void Printf(string name, int age, int number)
{	cout << name << " " << age << " " << number << endl;
}int main()
{function<void(int, int)> P1 = ::bind(Printf, "张三", std::placeholders::_1,         std::placeholders::_2);function<void(string, int, int)> P2 = Printf;function<void(string, int, int)> P3 = [](string name, int age, int number)->void{cout << name << " " << age << " " << number << endl;};P1(20, 5);P2("张三", 20, 5);P3("张三", 20, 5);return 0;
}

Args参数包

C++可变参数是指函数的参数个数是可变的,可以在函数定义时不确定参数的个数,需要在函数体内通过特定的语法来处理这些参数。

#include <iostream>// 递归终止条件
void print() {}// 使用参数包实现可变参数打印函数
template <typename T, typename... Args>//每次执行时都把参数包第一个参数拿出来给first。
//(准确的说是除了参数保外有多少个形参就应该取出多少个参数)
void print(T first, Args... args) {std::cout << first << std::endl;print(args...);
}//也可以直接写...代表参数包
//template <typename T>
//void print(T first, ...) {
//	std::cout << first << std::endl;
//	print(args...);
//}int main() {print(1, "hello", 3.14, "world");return 0;
}

抛异常

在C++中,异常处理的关键字包括:

  1. throw: 当程序在运行过程中发生异常时,可以使用throw关键字抛出一个异常对象。异常可以是任意的类型,通常是一个派生自std::exception的异常类对象。

  2. try: 使用try块来包裹可能引发异常的代码块。当异常被抛出时,程序会寻找与之匹配的catch块进行处理。

  3. catch: 在try块之后可以跟随一个或多个catch块,用来捕获并处理特定类型的异常。每个catch块可以处理不同类型的异常,也可以使用省略号(...)来捕获任意类型的异常。

 

void divide(int a, int b) {if (b == 0) {throw std::runtime_error("除以了0");}std::cout << "结果: " << a / b << std::endl;
}int main() {try {divide(10, 2);divide(8, 0); // 会引发异常}catch (const std::exception& e) {std::cerr << "捕获到异常: " << e.what() << std::endl;}catch (...){std::cout << "未知异常" << std::endl;}return 0;
}

 

 如果是嵌套的函数抛出异常在自己那层异常没有被捕获,就会层层返回直到异常被捕获。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FreeBSD下安装npm Node.js的22版本 并简单测试js服务器

FreeBSD下安装Node.js 在FreeBSD下安装Node.js很方便&#xff0c;直接pkg安装即可。 使用pkg install安装npm sudo pkg install npm-node22 Updating FreeBSD repository catalogue... Fetching data.pkg: 100% 7 MiB 2.5MB/s 00:03 Processing entries: 100% FreeB…

云原生可观测性体系:数字世界的神经感知网络

引言&#xff1a;从监控到全景式观测的范式升级 Datadog每日处理百万亿指标&#xff0c;Elastic APM实现万级服务拓扑动态发现。Grafana Loki日志分析延迟降至200ms内&#xff0c;Prometheus单集群支持千万时序存储。Uber通过全链路追踪压缩故障定位时间至秒级&#xff0c;Net…

基于VMware的Ubuntu22.04系统安装和配置以及解决Ubuntu共享文件夹无法实现的问题

一、前期准备 本次安装的虚拟机软件是 VMware Workstation Pro 17 登录跳转到 所有产品 进行下载 ​​​跳转到下载页面​​​ 选择 Windows 产品进行安装 勾选协议同意下载 离线版提供&#xff1a;大家根据自己电脑版本配置进行选择下载 本篇使用的虚拟机版本为 VMware Wor…

线程同步与互斥

目录 资源共享问题 &#xff08;一&#xff09;临界资源与临界区 &#xff08;二&#xff09;多线程并发访问问题 &#xff08;三&#xff09;锁 互斥锁原理 加锁原理 解锁原理 互斥锁相关操作接口 互斥锁封装 死锁 死锁产生的四个必要条件 解决死锁方法 &#xff…

SpringMVC 基本概念与代码示例

1. SpringMVC 简介 SpringMVC 是 Spring 框架中的一个 Web 层框架&#xff0c;基于 MVC&#xff08;Model-View-Controller&#xff09; 设计模式&#xff0c;提供了清晰的分层结构&#xff0c;适用于 Web 应用开发 SpringMVC 主要组件 DispatcherServlet&#xff08;前端控…

Banana Pi OpenWRT One Wifi6 OpenWrt社区官方开源路由器评测

第一款不可破解、开源、版权软件、符合 FCC、CE 和 RoHS 的维修权路由器 OpenWRT项目今年已经20岁了&#xff0c;为了纪念这一时刻&#xff0c;Banana Pi OpenWrt One/AP-24.XY路由器开发系统已经上市。这是OpenWRT团队与硬件公司的第一个联合项目。选择 Banana Pi&#xff0c;…

打造智能钉钉机器人:借助智谱GLM-4-Flash实现高效智能回复(文末附源码)

文章目录 前言一、准备工作&#xff08;一&#xff09;钉钉机器人&#xff08;二&#xff09;智谱 GLM-4-Flash&#xff08;三&#xff09;内网穿透工具 cpolar&#xff08;四&#xff09;需要准备的工具和环境 二、钉钉机器人的创建与配置步骤1&#xff1a;创建钉钉机器人步骤…

react基础语法视图层类组件

react基础语法视图层&类组件 MVVM *区别mvc&mvvm 两者的区别&#xff1a; 数据模型去渲染视图。数据层改了&#xff0c;vue自己会监听到帮我们拿最新的数据去渲染视图&#xff1b;构建数据构建视图&#xff0c;数据驱动的思想。这一套是非常相似的。 视图中的内容改变&…

数据结构--【顺序表与链表】笔记

顺序表 template <class T> class arrList :public List<T> //表示 arrList 类以公有继承的方式继承自 List<T> 类 //公有继承意味着 List<T> 类的公共成员在 arrList 类中仍然是公共成员&#xff0c;受保护成员在 arrList 类中仍然是受保护成员。 { …

Docker容器与宿主机目录映射深度解析

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 一、Docker容器与宿主机目录映射基础原理 在深入了解如何查询 Docker 容器目录在宿主机的映射目录之前&#xff0c;有必要先明晰其背后的基础原理。Docker 容器通过挂载&#xff08;mount&#xff09;机制将宿主机的…

p5.js:模拟 n个彩色小球在一个3D大球体内部弹跳

向 豆包 提问&#xff1a;编写一个 p5.js 脚本&#xff0c;模拟 42 个彩色小球在一个3D大球体内部弹跳。每个小球都应留下一条逐渐消失的轨迹。大球体应缓慢旋转&#xff0c;并显示透明的轮廓线。请确保实现适当的碰撞检测&#xff0c;使小球保持在球体内部。 cd p5-demo copy…

javascript-es6 (六)

编程思想 面向过程 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次 调用就可以了 就是按照我们分析好了的步骤&#xff0c;按照步骤解决问题 面向对象 面向对象是把事务分解成为一个个对象&…

Linux第0节:Linux环境的搭建

一、Linux 环境的搭建方式 搭建方式主要有三种&#xff1a; 直接安装在物理机上。但是由于 Linux 桌面使用起来非常不友好&#xff08;不推荐&#xff09;。使用虚拟机软件, 将 Linux 搭建在虚拟机上。但是由于当前的虚拟机软件(如 VMWare 之类的)存在一些 bug , 会导致环境上…

计算机网络:计算机网络的概念

1.计算机网络&#xff1a;由若干个结点和链接这些的链路组成。 2.集线器&#xff08;Hub&#xff09;&#xff1a;可以把多个结点连接起来&#xff0c;组成一个计算机网络。 不能避免数据冲突的情况 3.交换机&#xff08;Switch&#xff09;:可以把多个结点连接起来&#x…

mysql的锁-->一篇读懂所有锁机制

目录 mysql的锁 概述&#xff1a;根据mysql锁的大类型可以分为 我们先来讲一下范围最大的全局锁 使用 为什么要使用全局锁&#xff1f; 使用全局锁进行备份的缺点 表级锁 表锁 1.共享读表锁的语法 2.排斥写表锁 元数据锁 意向锁 什么是意向锁 怎么产生意向锁 意向…

Vue 实现智能检测文字是否溢出,溢出显示省略号,鼠标悬浮显示全部【附封装组件完整代码+详细注释+粘贴即食】

一、场景需求 在项目中&#xff0c;经常会遇到文本内容超出容器的情况。为了提高用户体验&#xff0c;我希望在文字溢出时显示悬浮提示&#xff0c;未溢出时则不显示。 二、效果演示 三、实现原理 DOM宽度对比法&#xff1a;通过比较元素的scrollWidth&#xff08;实际内容宽…

用Deepseek写一个 HTML 和 JavaScript 实现一个简单的飞机游戏

大家好&#xff01;今天我将分享如何使用 HTML 和 JavaScript 编写一个简单的飞机游戏。这个游戏的核心功能包括&#xff1a;控制飞机移动、发射子弹、敌机生成、碰撞检测和得分统计。代码简洁易懂&#xff0c;适合初学者学习和实践。 游戏功能概述 玩家控制&#xff1a;使用键…

《Spring日志整合与注入技术:从入门到精通》

1.Spring与日志框架的整合 1.Spring与日志框架进行整合&#xff0c;日志框架就可以在控制台中&#xff0c;输出Spring框架运行过程中的一些重要的信息。 好处&#xff1a;方便了解Spring框架的运行过程&#xff0c;利于程序的调试。 Spring如何整合日志框架 Spring5.x整合log4j…

关于mybatis查询时,时间字段的映射问题

目录 1.mysql中&#xff0c;关于时间的两种类型 1.1 date 1.2 datetime 2.mybatis从mysql数据库查询出上述两种类型的字段后&#xff0c;映射到Java实体类时的问题 3.结语 1.mysql中&#xff0c;关于时间的两种类型 1.1 date 格式&#xff1a;2002-09-23 特点&#xff1a…

高效自动化测试:打造Python+Requests+Pytest+Allure+YAML的接口测试框架

一、背景 在快节奏的开发周期中&#xff0c;如何确保接口质量&#xff1f;自动化测试是关键。通过构建标准化、可复用的测试框架&#xff0c;能显著提升测试效率与准确性&#xff0c;为项目质量保驾护航[1][7]。 二、目标 ✅ 核心目标&#xff1a; ● 实现快速、高效的接口测试…