当前位置: 首页 > news >正文

网站建设 费用预算高港区住房和城乡建设局网站

网站建设 费用预算,高港区住房和城乡建设局网站,公司网站制作企业,直播网站开发核心技术✅1主页#xff1a;#xff1a;我的代码爱吃辣 #x1f4c3;2知识讲解#xff1a;C11——右值引用 ☂️3开发环境#xff1a;Visual Studio 2022 #x1f4ac;4前言#xff1a;右值引用#xff0c;是C11更新的一个非常有价值的语法1主页我的代码爱吃辣 2知识讲解C11——右值引用 ☂️3开发环境Visual Studio 2022 4前言右值引用是C11更新的一个非常有价值的语法可以说是C为了追求极致的性能而出现的以前我们非常惧怕自定义类型的传值返回有了右值引用就还很多了。 目录 一.左值引用和右值引用 1.左值引用和右值引用 2.什么是右值什么是右值引用 二. 左值引用与右值引用比较 三.右值引用使用场景和意义 1.移动构造 2.移动赋值 3.STL中的容器都是增加了移动构造和移动赋值 ​编辑 四. 右值引用引用左值及其一些更深入的使用场景分析 五. 完美转发 1.模板中的 万能引用 2.std::forward 完美转发在传参的过程中保留对象原生类型属性 3.完美转发实际中的使用场景 一.左值引用和右值引用 传统的C语法中就有引用的语法而C11中新增了的右值引用语法特性所以从现在开始我们 之前学习的引用就叫做左值引用。无论左值引用还是右值引用都是给对象取别名。 1.左值引用和右值引用 左值是一个表示数据的表达式(如变量名或解引用的指针)我们可以获取它的地址可以对它赋 值左值可以出现赋值符号的左边右值不能出现在赋值符号左边。定义时const修饰符后的左 值不能给他赋值但是可以取它的地址。左值引用就是给左值的引用给左值取别名。 int main() {// 以下的p、b、c、*p都是左值int* p new int(0);int b 1;const int c 2;// 以下几个是对上面左值的左值引用int* rp p;int rb b;const int rc c;int pvalue *p;return 0; } 2.什么是右值什么是右值引用 右值也是一个表示数据的表达式如字面常量、表达式返回值函数返回值(这个不能是左值引 用返回)等等右值可以出现在赋值符号的右边但是不能出现出现在赋值符号的左边右值不能 取地址。右值引用就是对右值的引用给右值取别名。 int fmin(int a, int b) {return a; } int main() {double x 1.1, y 2.2;// 以下几个都是常见的右值10;x y;fmin(x, y);// 以下几个都是对右值的右值引用int rr1 10;double rr2 x y;double rr3 fmin(x, y);// 这里编译会报错error C2106: “”: 左操作数必须为左值10 1;x y 1;fmin(x, y) 1;return 0; } 注意右值是不能取地址的但是给右值取别名后会导致右值被存储到特定位置且可以取到该位置的地址也就是说例如不能取字面量10的地址但是rr1引用后可以对rr1取地 址也可以修改rr1。如果不想rr1被修改可以用const int rr1 去引用是不是感觉很神奇 这个了解一下实际中右值引用的使用场景并不在于此这个特性也不重要。 二. 左值引用与右值引用比较 左值引用总结 左值引用只能引用左值不能引用右值。 但是const左值引用既可引用左值也可引用右值。 int main() {// 左值引用只能引用左值不能引用右值。int a 10;int ra1 a; // ra为a的别名//int ra2 10;  // 编译失败因为10是右值// const左值引用既可引用左值也可引用右值。const int ra3 10;const int ra4 a;return 0; } 右值引用总结 右值引用只能右值不能引用左值。但是右值引用可以move以后的左值。 int main() {// 右值引用只能右值不能引用左值。int r1 10;// error C2440: “初始化”: 无法从“int”转换为“int ”// message : 无法将左值绑定到右值引用int a 10;int r2 a;// 右值引用可以引用move以后的左值int r3 std::move(a);return 0; } 三.右值引用使用场景和意义 前面我们可以看到左值引用既可以引用左值和又可以引用右值那为什么C11还要提出右值引用呢是不是化蛇添足呢下面我们来看看左值引用的短板右值引用是如何补齐这个短板的 1.移动构造 #includecassert namespace ikun {class string{public:string(const char* str ):_size(strlen(str)), _capacity(_size){//cout string(char* str)构造函数 endl;_str new char[_capacity 1];strcpy(_str, str);}// s1.swap(s2)void swap(string s){::swap(_str, s._str);::swap(_size, s._size);::swap(_capacity, s._capacity);}// 拷贝构造string(const string s):_str(nullptr){cout string(const string s) -- 深拷贝—拷贝构造 endl;string tmp(s._str);swap(tmp);}// 赋值重载string operator(const string s){cout string operator(string s) -- 深拷贝—赋值重载 endl;string tmp(s);swap(tmp);return *this;}~string(){delete[] _str;_str nullptr;}char operator[](size_t pos){assert(pos _size);return _str[pos];}void reserve(size_t n){if (n _capacity){char* tmp new char[n 1];strcpy(tmp, _str);delete[] _str;_str tmp;_capacity n;}}void push_back(char ch){if (_size _capacity){size_t newcapacity _capacity 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] ch;_size;_str[_size] \0;}//string operator(char ch)string operator(char ch){push_back(ch);return *this;}// stringstring operator(char ch){ikun::string str(this-c_str());str.push_back(ch);return str;}const char* c_str() const{return _str;}private:char* _str;size_t _size;size_t _capacity; // 不包含最后做标识的\0}; }int main() {ikun::string str(1111);ikun::string str1 str A;return 0; } 这种情况下避免避免不了的深拷贝。 如果我们有移动构造 首先我们先思考一个下面这个问题 答:次数的str是一个局部变量除了作用域就会销毁如果我们得到他的引用再次访问时就是非法的访问了。所以str只能作为传值返回但是传值返回有一个返回执行之后函数调用结束函数栈帧销毁伴随的局部变量也就销毁了编译器在处理时会使用一个临时变量来存储返回值。如果外面有接收再拷贝给外面这就是我们看到的图上画的两层拷贝构造。 右值也可以分为两种 纯右值字面量等。将亡值比如这里的返回的局部变量 str。 移动构造顾名思义可以将将亡值的资源移动到新的对象里从而节省拷贝得代价。 我们通过查看底层字符串的地址来进一步观察资源移动 int main() {ikun::string str(123);printf(str:%p\n, str.c_str());//将str强制变成右值ikun::string str1(move(str));printf(str:%p\n, str1.c_str());return 0; } 注意这里我们把s1 move处理以后, 会被当成右值调用移动构造但是这里要注意一般是不要这样用的因为我们会发现s1的资源被转移给了s3s1被置空了。  // 移动构造 string(string s):_str(nullptr), _size(0), _capacity(0) {cout string(string s) -- 移动语义—移动构造 endl;swap(s); } 2.移动赋值 #includecassert namespace ikun {class string{public:string(const char* str ):_size(strlen(str)), _capacity(_size){//cout string(char* str)构造函数 endl;_str new char[_capacity 1];strcpy(_str, str);}// s1.swap(s2)void swap(string s){::swap(_str, s._str);::swap(_size, s._size);::swap(_capacity, s._capacity);}// 拷贝构造string(const string s):_str(nullptr){cout string(const string s) -- 深拷贝—拷贝构造 endl;string tmp(s._str);swap(tmp);}// 赋值重载string operator(const string s){cout string operator(string s) -- 深拷贝—赋值重载 endl;string tmp(s);swap(tmp);return *this;}// 移动构造string(string s):_str(nullptr), _size(0), _capacity(0){cout string(string s) -- 移动语义—移动构造 endl;swap(s);}~string(){delete[] _str;_str nullptr;}char operator[](size_t pos){assert(pos _size);return _str[pos];}void reserve(size_t n){if (n _capacity){char* tmp new char[n 1];strcpy(tmp, _str);delete[] _str;_str tmp;_capacity n;}}void push_back(char ch){if (_size _capacity){size_t newcapacity _capacity 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] ch;_size;_str[_size] \0;}//string operator(char ch)string operator(char ch){push_back(ch);return *this;}// stringstring operator(char ch){ikun::string str(this-c_str());str.push_back(ch);return str;}const char* c_str() const{return _str;}private:char* _str;size_t _size;size_t _capacity; // 不包含最后做标识的\0}; }int main() {ikun::string str(1111);str ikun::string(123);return 0; }移动复制和移动构造基本一致 // 移动赋值 string operator(string s) {cout string operator(string s) -- 移动语义—移动赋值 endl;swap(s);return *this; } 3.STL中的容器都是增加了移动构造和移动赋值 四. 右值引用引用左值及其一些更深入的使用场景分析 按照语法右值引用只能引用右值但右值引用一定不能引用左值吗因为有些场景下可能 真的需要用右值去引用左值实现移动语义。当需要用右值引用引用一个左值时可以通过move 函数将左值转化为右值。C11中std::move()函数位于utility 头文件中该函数名字具有迷惑性它并不搬移任何东西唯一的功能就是将一个左值强制转化为右值引用然后实现移动语义。 STL容器插入接口函数也增加了右值引用版本  #includelist int main() {listikun::string lt;ikun::string s1(1111);// 这里调用的是拷贝构造lt.push_back(s1);// 下面调用都是移动构造lt.push_back(2222);lt.push_back(std::move(s1));return 0; } 五. 完美转发 1.模板中的 万能引用 模板中的不代表右值引用而是万能引用其既能接收左值又能接收右值模板的万能引用只是提供了能够接收同时接收左值引用和右值引用的能力但是引用类型的唯一作用就是限制了接收的类型后续使用中都退化成了左值我们希望能够在传递过程中保持它的左值或者右值的属性, 就需要用我们下面学习的完美转发。 void Fun(int x) { cout 左值引用 endl; } void Fun(const int x) { cout const 左值引用 endl; } void Fun(int x) { cout 右值引用 endl; } void Fun(const int x) { cout const 右值引用 endl; }templatetypename T void PerfectForward(T t) {Fun(t); } int main() {PerfectForward(10); // 右值int a;PerfectForward(a); // 左值PerfectForward(std::move(a)); // 右值const int b 8;PerfectForward(b); // const 左值PerfectForward(std::move(b)); // const 右值return 0; } 模板的万能引用只是提供了能够接收同时接收左值引用和右值引用的能力但是引用类型的唯一作用就是限制了接收的类型后续使用中都退化成了左值。所以这里都是左值在调用函数Fun 2.std::forward 完美转发在传参的过程中保留对象原生类型属性 void Fun(int x) { cout 左值引用 endl; } void Fun(const int x) { cout const 左值引用 endl; } void Fun(int x) { cout 右值引用 endl; } void Fun(const int x) { cout const 右值引用 endl; }templatetypename T void PerfectForward(T t) {// std::forwardT(t)在传参的过程中保持了t的原生类型属性。Fun(std::forwardT(t)); } int main() {PerfectForward(10); // 右值int a;PerfectForward(a); // 左值PerfectForward(std::move(a)); // 右值const int b 8;PerfectForward(b); // const 左值PerfectForward(std::move(b)); // const 右值return 0;} 3.完美转发实际中的使用场景 templateclass T struct ListNode {ListNode* _next nullptr;ListNode* _prev nullptr;T _data; }; templateclass T class List {typedef ListNodeT Node; public:List(){_head new Node;_head-_next _head;_head-_prev _head;}void PushBack(T x){//Insert(_head, x);Insert(_head, std::forwardT(x));// 关键位置}void PushFront(T x){//Insert(_head-_next, x);Insert(_head-_next, std::forwardT(x));// 关键位置}void Insert(Node* pos, T x){Node* prev pos-_prev;Node* newnode new Node;newnode-_data std::forwardT(x); // 关键位置// prev newnode posprev-_next newnode;newnode-_prev prev;newnode-_next pos;pos-_prev newnode;}void Insert(Node* pos, const T x){Node* prev pos-_prev;Node* newnode new Node;newnode-_data x; // 关键位置prev-_next newnode;newnode-_prev prev;newnode-_next pos;pos-_prev newnode;} private:Node* _head; };
http://www.zqtcl.cn/news/161124/

相关文章:

  • 怎么用织梦修改建设一个新的网站小程序无代码开发平台
  • 网站建设询价外贸网页制作公司哪家好
  • 网页设计与网站建设报告ckplayer整合WordPress
  • 厦门APP开发网站开发公司百度热搜榜单
  • 网站排名英文怎么说网页编辑器在线使用
  • 湖南做防水堵漏工程商网站网站建设编程软件
  • 网站编辑专题怎么做徐州建筑工程招投标网站
  • 英文网站建设合同招考网站开发
  • 网上商城网站 找什么做dede本地环境搭建网站
  • 网站开发遇到的问题及解决方法深圳市做网站有哪些公司
  • 自媒体网站 程序18款免费软件app下载推荐
  • 产业园门户网站建设方案瑞昌网络推广
  • 长春市网站建设动漫wordpress主题下载地址
  • 如何做专业的模板下载网站wordpress 多网址
  • 做qq头像的网站wordpress 安装 服务器 系统
  • 怎样查网站的注册地点百度小说排行榜2021
  • 网站建设中中文模板wordpress siren
  • 设计本官方网站电脑版附近室内装修公司电话
  • 服务外包网站wordpress 禁止转载
  • l礼品文化网站建设不常见的网络营销方式
  • 做网站侵权腾讯企点打不开
  • iis 网站拒绝显示此网页上海网站建设类岗位
  • 营销型网站建设推荐google关键词
  • 网站上线是前端还是后端来做如何做垂直门户网站
  • 网站建设与管理2018海尔集团网站 建设目的
  • ps做网站大小wordpress调用 php文件
  • php网站忘记后台密码江苏网页制作报价
  • 网站模板 哪个好完备的常州网站推广
  • 衡水淘宝的网站建设濮阳市城乡一体化示范区主任
  • 公司网上注册在哪个网站商洛市商南县城乡建设局网站