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

惠通网站建设网站设置专栏

惠通网站建设,网站设置专栏,湖南长沙发掘了3座西汉时期墓葬,健康码行程码防疫一体机在此之前#xff0c;我们所用的引用#xff0c;其实都是左值引用。 int a 10; int ra a; 下面我们来重新认识一下引用#xff1a; 而何为左值#xff1f;左值引用其实是什么#xff1f;请往下看~ 左值是一个表示数据的表达式(如变量名或解引用的指针)#xff…在此之前我们所用的引用其实都是左值引用。 int a 10; int ra a; 下面我们来重新认识一下引用 而何为左值左值引用其实是什么请往下看~ 左值是一个表示数据的表达式(如变量名或解引用的指针)我们可以获取它的地址可以对它赋值左值可以出现赋值符号的左边也可以出现在赋值符号的右边。定义时const修饰符后的左 值不能给它赋值但是可以取它的地址。左值引用就是给左值的引用给左值取别名。 例如 int main() {//左值变量名/解引用的指针// 以下的p、b、c、*p都是左值int* p new int(0); //p是变量名为左值 *p为解引用的指针int b 1; // b为变量名const int c 2; //c为变量名。加上const后c的值不能被修改c 3;//error//左值引用// 以下几个是对上面左值的左值引用int* rp p; //对p进行引用rp为p的别名int rb b;const int rc c;int pvalue *p; return 0; } 右值是什么右值引用呢 右值也是一个表示数据的表达式如字面常量、表达式返回值函数返回值(这个不能是左值引用返回)等等右值可以出现在赋值符号的右边但是不能出现在赋值符号的左边右值不能取地址。右值引用就是对右值的引用给右值取别名。 右值引用是用两个表示左值引用是用一个表示。 int main() {//右值字面常量、表达式返回值、函数返回值double x 1.1, y 2.2;// 以下几个都是常见的右值10; //字面常量x y; //表达式返回值即return x y;fmin(x, y); //函数返回值// 以下几个都是对右值的右值引用int rr1 10;rr1 20;//注意这里int* prr1 rr1; //注意这里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修饰的左值引用可以引用左值和右值。因为有了const修饰要么是权限的平移要么是权限的缩小。 ③右值引用只能引用右值不能引用左值。 ④右值可以引用move后的左值。函数move的作用是让左值变成右值去使用。 int main() {// ①左值引用只能引用左值不能引用右值。int a 10; int ra1 a; // ra1为a的别名左值引用引用左值a为左值//int ra2 10; // 编译失败因为10是右值左值引用不能引用右值// ②const左值引用既可引用左值也可引用右值。const int ra3 10;const int ra4 a;// ③右值引用只能右值不能引用左值。int r1 10;// error C2440: “初始化”: 无法从“int”转换为“int ”// message : 无法将左值绑定到右值引用int a 10;int r2 a; //a是左值是右值引用右值引用不能引用左值// 右值引用可以引用move以后的左值int r3 std::move(a);return 0; }右值引用的作用和意义 左值引用很好因为左值引用的存在在函数传参和函数传返回值的时候减少了拷贝从而提高了效率。但是存在这样一个问题在一个函数中如果要使用左值引用作为返回值那么这个返回的变量的生命周期必须不能随函数的销毁而销毁 看下面代码 //函数传参使用左值引用减少拷贝 templateclass T void func1(const T x) {}//函数传返回值使用左值引用减少拷贝 //返回的x是传进来的参数x不会随函数的销毁而销毁。 templateclass T const T func2(const T x) {// ...return x; }//ret为函数栈帧中的变量会随函数的销毁而销毁 //ret做返回值这种情况下就得进行拷贝 templateclass T T func3(const T x) {T ret;// ...return ret; } 对于前两种情况都可以使用左值引用减少拷贝。但是对于第三种情况在没有认识到右值引用的时候它就必须进行拷贝。 这就是左值引用未能解决的场景问题。因此右值引用的价值之一就是补齐左值引用的这一个短板。 这里选择复用我们自己模拟实现string类的代码作为测试代码模拟实现string类 这里将对string类添加右值引用的移动构造和移动赋值 在此之前我们先来看看在没有实现移动构造和移动赋值之前以下代码的结果如何 string to_string(int value){bool flag true;if (value 0){flag false;value 0 - value;}my_string::string str;while (value 0){int x value % 10;value / 10;str (0 x);}if (flag false){str -;}std::reverse(str.begin(), str.end());return str;} int main() {my_string::string ret; ret my_string::to_string(-1234);return 0; } 结果如下 在调用to_string的时候传值传参调用一次深拷贝。返回值返回的时候因为没有移动构造调用就会调用拷贝构造因为const左值引用可以引用右值因此会调用深拷贝。赋值给ret的时候也调用了一次深拷贝。 在代码中-1234是常量为右值。但是在模拟的string类中并没有专门右值引用的构造并且对ret的赋值也是右值但是没有右值引用的赋值只能去调用深拷贝因为深拷贝的左值引用加了const修饰。 接着我们加入右值引用的移动拷贝和移动构造 在实现这两个接口前在上文中提到了右值引用的两种形式纯右值和将亡值。 我们来看将亡值从名字中可以看出这种右值是即将失去生命的值也就是生命周期快到了往后的代码程序中不需要它因此我们可以利用将亡值进行一次移动构造和移动赋值 既然都将亡了那么我就用我的吸星大法将你的功力吸走因此实现的思路就是交换 // 移动构造string(string s){cout string(const string s) -- 移动拷贝 endl;swap(s);}// 移动赋值string operator(string s){cout string operator(string s) -- 移动赋值 endl;swap(s);return *this;} 上述测试代码的结果变成了这样的 我们自己实现的to_string在传入-1234作为参数此时拷贝的是使用移动拷贝而str作为函数里面的变量在返回值返回的时候是作为右值调用移动赋值赋值给ret减少了拷贝 整体测试代码如下 namespace my_string {class string{public:typedef char* iterator;iterator begin(){return _str;}iterator end(){return _str _size;}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){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){cout string(const string s) -- 移动拷贝 endl;swap(s);}// 移动赋值string operator(string s){cout string operator(string s) -- 移动赋值 endl;swap(s);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;}const char* c_str() const{return _str;}private:char* _str nullptr;size_t _size 0;size_t _capacity 0; // 不包含最后做标识的\0};//转化成字符串string to_string(int value){bool flag true;if (value 0){flag false;value 0 - value;}my_string::string str;while (value 0){int x value % 10;value / 10;str (0 x);}if (flag false){str -;}std::reverse(str.begin(), str.end());return str;} }int main() {my_string::string ret; ret my_string::to_string(-1234);return 0; } 总结一下右值引用和左值引用对减少拷贝的方式 右值引用和左值引用减少拷贝的原理不一样。左值引用减少拷贝的方法是起别名直接起作用而右值引用减少拷贝的方法是实现移动拷贝和移动赋值在将亡值的情况下直接转移资源间接起作用。 右值引用的价值之二对于插入一些插入右值数据也可以减少拷贝 比如list容器如果插入接口insert的传值是左值引用那么在插入右值的时候由于没有移动拷贝并且加了const修饰此时的左值引用可以引用右值调用的是深拷贝。 而如果使用了移动拷贝参数为右值引用那么就会采用移动拷贝减少了拷贝的次数 未完待续......
http://www.dnsts.com.cn/news/174197.html

相关文章:

  • 惠州做棋牌网站建设自动更新的网站建设
  • 连云港市住房和城乡建设局网站企业网站建设的类型主要有
  • 阳江网络问政平台首页网站优化知识资讯
  • 中国十大电商平台排名前十名seo的目的是什么
  • 怎样做网站后台什么是互联网营销
  • 大良建网站一流的镇江网站优化
  • 中国空间站设计在轨飞行几年wordpress 数据库导出
  • 网站建设与部署阿里云大学寺庙 网站建设
  • 花都建站网站icp备案费用
  • 怎么知道网站是某个公司做的个人简历通用免费模板
  • 国外购物网站建设html5官网首页
  • python做网站效率网站权重传递
  • 社交模板网站建设用模板做的网站权重高吗
  • android网站开发视频教程专业手机网站怎么做
  • 十大战略咨询公司上海seo优化公司
  • 网站建设与开发 教材怎么开发一个微信商城
  • 通过服务推广网站的案例最新舆情信息网
  • 网站和网页建设题目wordpress 分类目录 标签转换器
  • 企业网站群建设方案做俄罗斯外贸的网站
  • 网站开发公司一站式服务wordpress修改评论
  • python做音乐网站wordpress 文章 attachment_id
  • 广东省建设厅投诉网站推广普通话标语
  • 阜宁县网站建设北京网站建站公
  • 网站开发分页代码东莞网络推广培训班
  • 手把手做网站页面东莞企业网站多少钱
  • 全球网站排行网上帮别人做网站
  • 企业可以做哪些网站有哪些购物网站建设思维导构图
  • 建设网站图片做网站和做平台的区别
  • 手表网站海马300米潜水表佛山网站常见的问题
  • 浙江省人才网官方网站建设厅招聘西柏坡旅游网站建设规划书