【C++】C++11新增特性
目录
C++11简介:
1、统一的列表初始化:
std::initializer_list
2、自动类型推导:
auto:
decltype:
3、final 和 override
final:
override:
4、默认成员函数控制:
显示缺省函数:
删除默认函数:
5、左值和右值:
概念补充:
代码示例:
左值引用与右值引用:
两者的联系和区别:
右值引用的意义:
6、完美转发:
7、lambda表达式:
8、可变参数列表:
9、包装器:
function包装器:
bind(绑定):
C++11简介:
C++11,也被称为C++0x,是C++编程语言的一个重要更新版本,它于2011年正式被ISO标准委员会批准。相比于C++98,C++11带来了大量的新特性和改进,其中包含了约140个新特性,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率。本篇主要介绍一些使用的多且实用的一些语法:
1、统一的列表初始化:
在C++98中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。例如:
C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自 定义的类型,使用初始化列表时,可添加等号(=),也可不添加。
struct Student
{int _x;int _y;
};
int main()
{// 两种写法一样的int x1 = 1;int x2{ 2 };// 可以省去 = int array1[]{ 1, 2, 3, 4, 5 };int array2[5]{ 0 };Student s{ 1, 2 };return 0;
}
创建对象时也可以使用列表初始化方式调用构造函数初始化
class A
{
public:// 如果不想让隐式类型转换发生可以加关键字: explicit// explicit A(int x, int y)A(int x, int y):_x(x), _y(y){}// 单参数A(int x):_x(x), _y(x){}private:int _x;int _y;
};int main()
{// 多参数的隐式类型转换// 本质是构造一个A对象,然后用这个对象去拷贝构造(编译器会进行优化, 就变成了直接构造)A a1 = { 1,2 };// 例如: A& a3 = {2, 2}; 这样子的就不行,但转换成下面的就可以const A& a3 = { 2,2 }; // 因为右边会产生临时变量,但临时变量具有常性// 当然也可以不加 = ,如 A a1{ 1,2 }; 但是不太推荐这么写 return 0;
}
std::initializer_list
initializer_list
是 C++11 引入的一个特性,用于表示某种类型对象的数组。它允许使用花括号 {} 包围的初始值列表来初始化对象或函数参数。initializer_list
通常与构造函数结合使用,以提供一种灵活的方式来初始化集合(如数组、向量等)或执行基于多个值的初始化。
(本质就是一个常量数组)
是个容器,但是没有新开空间,里面有两个指针,一个指向第一个元素(常量数组的开始),一个指向最后一个元素的后一个位置(常量数组的结束),所以是8/16字节,因为是两个指针(first, last)
2、自动类型推导:
auto:
auto 关键字用于自动类型推导。编译器会根据初始化表达式自动推断出变量的类型。使用 auto 可以让代码更加简洁,例如STL容器迭代器、函数返回类型等。
缺陷:
auto虽然用起来非常方便,但也不能滥用哦,例如在层层嵌套的函数当中,用起来是爽了,但是代码的可读性会大大下降,这时维护起来也会特别麻烦,一个变量可能得剥好几层才知道类型,还有在涉及到函数重载以及模板元编程时,容易引发错误和意外的行为。
decltype:
decltype 关键字用于查询表达式的类型。与 auto 不同,decltype 在编译时解析表达式并得到其类型,但不实际计算表达式的值。这意味着可以使用 decltype 来获得几乎任何表达式的类型,包括那些没有定义(或不可计算)的表达式。
缺陷:
decltype的语法相对复杂一点,且在某些情况下,decltype导出的类型可能非常冗长,特别是当表达式涉及到模板类型或复杂函数时。如果在函数声明中使用decltype时,如果函数的返回类型依赖于模板参数或函数参数的类型,那么可能需要使用尾置返回类型(trailing return type)语法,这可能会使函数声明的复杂性增加。
3、final 和 override
final:
final修饰类的时候,表示这个类无法被继承、修饰虚函数时,表示这个虚函数不能被重写。
修饰类:
修饰虚函数:
override:
override 关键字用于检查派生类虚函数是否重写了基类的某个虚函数,如果没有重写编译报错。
4、默认成员函数控制:
显示缺省函数:
当你不为类定义任何构造函数时,编译器会为你生成一个默认构造函数。如果你显式地定义了其他构造函数(例如拷贝构造、移动构造还是其他自定义构造函数),但没有定义默认构造函数,编译器不会自动生成默认构造函数。如果还想编译器生成默认构造函数的话,可以在类定义中显式地使用 default 关键字来请求编译器生成默认构造函数。
删除默认函数:
如果想要一个类禁止被拷贝,在C++98当中的做法是将这个类的拷贝构造以及赋值重载直接声明为私有(private),在C++11中则更为简单一些,只需在该函数声明加上delete关键字即可:
5、左值和右值:
概念补充:
左值是一个表示数据的表达式(如变量名或解引用的指针),我们可以获取它的地址+可以对它赋值,左值可以出现赋值符号的左边,右值不能出现在赋值符号左边。定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址。左值引用就是给左值的引用,给左值取别名。
右值也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值(这个不能是左值引用的返回)等等,右值可以出现在赋值符号的右边,但是不能出现在赋值符号的左边,右值不能取地址。右值引用就是对右值的引用,给右值取别名。
简记:左值能出现在右边,右值不能出现在左边。
代码示例:
左值引用与右值引用:
可以先简短的记着:左值引用就是给左值取别名,右值引用就是给右值取别名!
先来谈谈简单的:左值引用:
int main()
{int a = 10;int& b = a; // b就是a的别名,其实就是a// 属于同一块地址空间:cout << &a << endl;cout << &b << endl;return 0;
}
再来谈谈右值引用:
int main()
{int x = 1, y = 2;int&& z = (x + y);string&& s1 = string("111111");string&& s2 = to_string(1234);int&& a = 10;return 0;
}
两者的联系和区别:
右值引用的本身是左值,因为只有这样才能实现移动构造和移动赋值,以此来实现资源转移,因为普通左值是没法引用右值的,必须加const,但是加了又没法实现资源的转移。
所以右值引用是有地址的:
string&& s1 = string("111111");cout << &s1 << endl;
如果右值引用的属性是右值,那么移动构造和移动赋值,要转移资源的语法逻辑是矛盾的,右值是不能被改变的,可以理解为右值带有const属性。
诶?那再回头来看看,既然右值引用是给右值取别名,那么右值引用有地址,那么是不是右值本身是有地址的???
其实还真是,像刚才的那种右值的底层是有地址的,但是只有编译器知道,为了语法的逻辑自洽,他不会让你取得到这个地址,右值引用s1其实就是变相获取到这个地址,所以能不能取到地址不是关键,关键是资源的转移(匿名对象和临时对象都带有const属性)
一般情况下左值引用只能引用左值,不能引用右值。但是加了const的左值引用既能引用左值也能引用右值。
一般情况下右值引用只能引用右值,不能引用左值。但是右值引用可以引用move以后的左值。
move函数:将一个左值对象转化为右值引用,从而允许使用移动语义来优化资源的管理和程序的性能。
右值引用的意义:
右值引用的意义主要体现在两个方面:移动语义、完美转发。
移动语义:
1、资源所有权转移:在C++中,类的右值通常是一个临时对象,如果在表达式结束时没有被绑定到引用,就会被废弃。通过右值引用,可以在对象被废弃之前移走其资源,实现资源的再利用,再需要时,就可以避免无意义的拷贝复制操作,提高效率。
2、减少开销:被移走资源的右值在废弃时已经成为空壳,其析构的开销会大大降低。这有助于提升程序的性能,特别是在处理大型对象或资源密集型操作时。
完美转发:
这里简单讲一下,下一标题再详细叙述。
完美转发的实现依赖于右值引用。右值引用(T&&)用于绑定到即将被销毁的对象上,从而允许资源的移动而非拷贝。
在模板函数中,通过使用 T&& 作为参数类型,能够接受左值和右值作为参数。
6、完美转发:
完美转发(Perfect Forwarding)是C++11中引入的一种编程技巧,其目的是在编写泛型函数时能够保留参数的类型和值类别(左值或右值),从而实现更为高效且准确地传递参数。
完美转发允许函数模板将其接收到的参数“完美”地转发给内部调用的其他函数,这里的“完美”指的是不仅能准确地转发参数的值,还能保证被转发参数的左、右值属性不变。
省流:
完美转发就是在函数模板中,将参数转发给其他函数时,可以锁定参数的左右值属性和值类别。
因为右值引用的对象在作为实参传递时,属性会退化为左值,会直接匹配左值引用,使用完美转发可以保持它的右值属性。
这里来认识两个东西:forward函数和万能引用(T &&)
forward函数:是一个模板函数,用于实现完美转发
万能引用(T &&):既能接收左值也能接收右值。
直接上一段代码来直观感受一下:
7、lambda表达式:
lambda表达式从C++11标准开始引入的一种定义匿名函数对象的简洁方式。它可以捕获它所在作用域的变量,并可以在需要函数对象的任何地方使用,包括作为算法的一部分或作为回调函数。
基本语法:
[capture](parameters) mutable -> return_type { // 函数体 }
- capture:捕获列表,指定哪些外部变量在lambda函数体内是可用的。捕获列表可以是按值捕获(例如
[x]
)或按引用捕获(例如[&x]
),也可以混合使用(例如[&, x = this->x]
),其中&
表示按引用捕获所有外部变量,除了显式按值捕获的。=
表示按值捕获所有外部变量,除了显式按引用捕获的。- parameters:参数列表,与普通函数相同。如果lambda不接受任何参数,则可以省略括号。
- mutable:这是一个可选的说明符,表示lambda函数体内的代码可以修改按值捕获的变量。默认情况下,这些变量是只读的。
- return_type:返回类型,也是可选的。如果lambda体只有一个返回语句,且编译器能够从该语句推断出返回类型,则可以省略。如果lambda没有返回语句,则其返回类型为
void
。
也可以就简单的记为:[](){}
其实本质就是仿函数,编译器在编译的时候就会转成仿函数,原理类似范围for
举个小例子:我给这个lambda表达式传两个值,让它返回这两个值的和给我:
补充:
int main()
{int a = 1, b = 2;// 捕捉列表auto swap1 = [a, b]() mutable // 还是传值捕捉{int tmp = a;a = b;b = tmp;};swap1();// 如果不加mutable的话a, b捕捉到的默认是const的,无法对其做出修改操作,而且·此ab非局部的那俩ab// 也就是就算带mutable修改内部也并不会改变外部printf("%d %d\n", a, b);// 引用捕捉可修改:auto swap2 = [&a, &b]() {int tmp = a;a = b;b = tmp;};swap2();printf("%d %d", a, b);// 捕捉方式还有 =, &// = 为传值捕捉所有父作用域中的变量,包括this// & 为引用捕捉所有父作用域中的变量,包括this// 还可以混合捕捉: 表示为&捕捉全局,唯独b为传值捕捉(也可以反着来)auto func = [&, b]() {};return 0;
}
8、可变参数列表:
省流:可变参数列表一种特殊的函数参数机制,允许函数接收数量不确定的参数。
先来段简单的代码看看使用方法:
既然可变参数列表可以接收不确定数量的参数,那么仔细想想,好像printf函数也是如此,那么是不是就可以简单的模拟实现一下printf函数呢?
总结:可变参数列表提供了极高的灵活性和类型安全性,且支持泛型编程,但复杂性较高,可能会导致编译时间的增加和额外的性能开销。
9、包装器:
function包装器:
function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。于头文件#include <functional>
中
其实包装器的本质就是函数指针,可调用对象有:函数、函数对象(仿函数)、lambda表达式、绑定表达式等。
先来看一个例子:来看看下面这段代码中的函数模板会被实例化几次?
template<class F, class T>
T Test(F f, T t)
{static int x = 0;cout << "x: " << ++x << endl;cout << "x: " << &x << endl;return f(t);
}double f(double i)
{return i / 2;
}// 仿函数
struct Functor
{double operator()(double d){return d / 3;}
};int main()
{// 函数:cout << Test(f, 11.11) << endl;// 函数对象(仿函数):cout << Test(Functor(), 11.11) << endl;// lambda表达式:cout << Test([](double d) {return d / 4; }, 11.11) << endl;return 0;
}
通过结果我们可以看出来,函数模板实例化了三次(静态变量x的地址都不一样)
对于同一个模板类或模板函数,使用多种不同的类型参数去实例化它时。每次使用不同的类型参数实例化模板,编译器都会生成一份独立的模板代码。这可能导致编译时间增加、二进制文件大小膨胀,以及潜在的运行时性能问题(如指令缓存未命中增加)。
但是我只想让这个函数模板实例化一次怎么办呢?
这时就可以掏出function包装器来解决:
function用法解析:
代码结果:
这样实例化出来的就是同一份模板了(x依次递增,且为同一地址),这样通过function包装器就可以减少不必要的模板实例化,因为模板实例化多了容易导致代码膨胀,降低效率。
最重要的是:好用(滑稽)
bind(绑定):
省流:调整可调用对象的参数个数或者顺序:
完整概念:
std::bind
用于生成一个新的可调用实体(function object),这个新的可调用实体可以把它的某些(或全部)参数绑定到给定的值上。这样,当你调用这个新的可调用实体时,就不需要再为那些已经被绑定的参数提供值了。(头文件:#include <functional>
)
基本语法:
auto newCallable = bind(callable, arg_list, placeholders::_1, placeholders::_2, ...);
- callable:你想要调用的函数、函数对象、成员函数指针或成员对象指针。
- arg_list:你希望预先绑定到 callable 的参数列表。这些参数在后续调用 newCallable 时将不再需要。
- placeholders::_1, placeholders::_2, ...:占位符,用于表示 newCallable 被调用时,需要接收的参数位置。允许保留一些参数位置以供将来调用时提供。
上个简单的代码看看:
再来看一组:也可以绑定类中的函数:
注意:
绑定成员函数时,需要传递成员函数的地址(使用&
运算符),并且还需要传递一个指向对象实例的指针(对于非静态成员函数)或对象的引用(但通常期望指针,因为bind需要能够存储这个引用所指向的对象的状态,而局部引用在函数返回后可能不再有效)。
相关文章:

【C++】C++11新增特性
目录 C11简介: 1、统一的列表初始化: std::initializer_list 2、自动类型推导: auto: decltype: 3、final 和 override final: override: 4、默认成员函数控制: 显示缺省…...

【LeetCode每日一题】——662.二叉树最大宽度
文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 广度优先搜索 二【题目难度】 中等 三【题目编号】 662.二叉树最大宽度 四【题目描述】 给…...

第二十三节、血量更新逻辑的实现
一、创建代码 引入命名空间 using UnityEngine.UI; 调用UI必须有这个代码 二、ScriptObject类 1、是一个持久化存储文件的类型 接收所有的事件方法 先继承SO类,然后创建项目菜单 2、进行订阅 放入事件类,关联代码,即可进行广播 传递给这…...
Spring Authorization Server 认证服务器搭建
Spring Authorization Server实现了oauth2和oidc,最近有了解相关技术的需求,所以就尝试着进行了基本的环境搭建和技术测试,目前只测试了授权码模式,做一个记录,后续需要用时方便查找和参考。 1. 版本要求 Spring Authorization Server 版本:1.3.1 JDK 版本:17 Spring B…...

秋招突击——8/15——知识补充——垃圾回收机制
文章目录 引言正文指针引用可达性分析算法垃圾回收算法标记清除算法标记整理算法复制分代收集 垃圾收集器Serial收集器ParNew并行收集器Parallel Scavenge吞吐量优先收集器Serial Old老年代收集器Parallel old收集器CMS收集器G1收集器(Garbage First垃圾优先&#x…...

【iOS】UITableViewCell的重用问题解决方法
我自己在实验中对cell的重用总结如下: 非自定义Cell和非自定义cell的复用情况一样: 第一次加载创建tableView的时候,是屏幕上最多也显示几行cell就先创建几个cell,此时复用池里什么都没有开始下滑tableView,刚开始滑…...
开发一个微信小程序商城需要哪些技术栈
开发一个小程序商城需要掌握以下技术栈: 前端技术:包括HTML、CSS和JavaScript,用于定义商城的页面结构、样式设计和交互功能。 微信小程序专用技术:如WXML、WXSS、JavaScript和JSON,用于描述小程…...

望繁信科技荣膺上海市浦东新区博士后创新实践基地称号
近日,上海望繁信科技有限公司(简称“望繁信科技”)凭借在大数据流程智能领域的卓越表现,成功入选上海市浦东新区博士后创新实践基地。这一荣誉不仅是对望繁信科技创新能力和技术实力的高度认可,也标志着公司在推动产学…...

Nginx--代理与负载均衡(扩展nginx配置7层协议及4层协议方法、会话保持)
前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 一、代理原理 1、反向代理产生的背景 单个服务器的处理客户端(用户)请求能力有一个极限,当接入请求过多时&#…...

Ubuntu20.4 系统安装后无wifi图标
0. 问题排查 1.检查 BIOS 设置: 有时候,无线网卡可能在 BIOS 中被禁用。重启电脑,进入 BIOS 设置,确保无线网卡选项是启用的。 2.检查硬件开关: 检查您的笔记本电脑是否有物理开关或键盘快捷键来启用或禁用无线网卡。 3.在软件更新中切换…...

牛客网SQL进阶135 :每个6/7级用户活跃情况
每个67级用户活跃情况_牛客题霸_牛客网 0 问题描述 基于用户信息表user_info、、试卷作答记录表exam_record、题目练习记录表practice_record,统计 每个6/7级用户总活跃月份数、2021年活跃天数、2021年试卷作答活跃天数、2021年答题活跃天数,结果 按照总…...
SQLite3使用接口写入二进制文件
使用接口的方式写入二进制文件 ,有二种方案。 一、全部文件 一次性写下到数据中 使用sqlite3_bind_blob接口 FILE* fpfopen("user.bmp","rb"); iLenfread(buffer,1,65535,fp); fclose(fp);sqlite3_prepare(pDB,"insert into user values …...
在复杂的数据库架构中,如何优化 SQL 查询以提高性能和减少资源消耗?
在优化 SQL 查询以提高性能和减少资源消耗时,可以考虑以下几个方面: 使用索引:为经常被查询的列创建索引,可以大大加快查询速度。同时,避免过多的索引,因为过多的索引会增加写入操作的开销。 编写高效的查…...

【HarmonyOS】端云一体化初始化项目
简介 端云一体化开发是HarmonyOS对云端开发的支持、实现端云联动。云开发服务提供了云函数、云数据库、云存储等服务,可以使开发者专注于应用的业务逻辑开发,无需关注基础设施,例如:服务器、操作系统等问题。 因此,…...
LLM之KG:利用大语言模型(LLM)对文本语料提取概念和概念之间的语义关系进而实现自动构建知识图谱
LLM之KG:利用大语言模型(LLM)对文本语料提取概念和概念之间的语义关系进而实现自动构建知识图谱 目录 ML之KG:基于MovieLens电影评分数据集利用基于知识图谱的推荐算法(networkx+基于路径相似度的方法)实现对用户进行Top电影推荐案例 LLMs之AutoKG:《大型语言模型在知识图…...
Spring Security 6如何使用?
Spring Security 6 是一个功能强大且高度可定制的身份验证和访问控制框架,它专注于为基于Java的应用程序提供全面的安全解决方案。以下是对Spring Security 6的详细解析: 一、核心功能 身份验证(Authentication): 验…...

PyTorch深度学习快速入门教程--学习笔记
目录 P4 PyCharm和Jupyter的对比 P5 PyTorch加载数据 P6 Dataset类代码实现 P7 Tensorboard 写日志 读取日志文件 Tensorboard 读图片 P10 Transforms使用 Transforms用途 常见的Transforms工具 P14 torchvision数据集使用 P15 Dataloader使用 P16 nn.Module模块使…...
SQLALchemy 分组过滤、子查询
SQLALchemy 分组过滤、子查询 分组和过滤(Group By Having)示例:使用ORM示例:使用SQLAlchemy Core子查询(Subquery)SQLAlchemy 是一个流行的 SQL 工具包和对象关系映射(ORM)库,用于 Python 应用程序。它允许你以 Pythonic 的方式使用 SQL 数据库,同时提供了强大的查询…...
华为od(D卷) 环中最长子串/字符成环找偶数LOX
文章目录 题目描述输入描述输出描述示例1示例2示例3思路代码 题目描述 给你一个字符串 s,字符串 s 首尾相连成一个环形,请你在环中找出 ‘l’、‘o’、‘x’ 字符都恰好出现了偶数次最长子字符串的长度。 输入描述 输入是一串小写的字母组成的字符串 …...

机器学习--常见算法总结
有监督学习算法 1. 线性回归算法 概念:线性回归是一种统计方法,用于预测一个变量(因变量)与一个或多个自变量(特征变量)之间的关系。目标是通过线性方程建立自变量和因变量之间的关系模型。 作用&#x…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...