经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
c/c++ 拷贝控制 右值与const引用
来源:cnblogs  作者:小石王  时间:2018/12/3 23:55:22  对本文有异议

拷贝控制 右值与const引用

背景:当一个函数的返回值是自定义类型时,调用侧用什么类型接收??

1,如果自定义类型的拷贝构造函数的参数用const修饰了:可以用下面的方式接收。

  1. Test t2 = fun(t1);

2,如果自定义类型的拷贝构造函数的参数没有用const修饰了:必须用下面的方式接收

  1. const Test& t2 = fun(t1);
  2. Test t2 = fun(t1);//编译不通过

编译错误:

  1. cannot bind non-const lvalue reference of type Test&’ to an rvalue of type Test

解释:

第一种条件下,用const了,由于在编译阶段,要调用Test的拷贝构造函数(其实,在运行的时候是没有调用这个拷贝构造函数的,编译器进行了优化,避免了一次没有意义的拷贝。),参数是fun(t1)的返回值,类似Test(func(t1)),但是这个参数,也就是函数的返回值是右值(临时对象),由于右值必须是const属性的,所以加上了const,就满足了右值的需要,所以可以编译通过,这时t2是可以被改变的;如果没有加const,用第一种方式(Test t2 = fun(t1);)接收,就会编译错误。

第二种条件下,没有使用const,由于在编译阶段,要调用Test的拷贝构造函数,因为fun(t1)的返回值是右值,右值有const属性,所以编译器没有找到匹配的拷贝构造函数,就自己合成了一个拷贝构造函数。由编译器合成的这个拷贝构造函数就只能用上面写的方式接收,至于为什么,还没搞不懂!!!

代码:

  1. #include <iostream>
  2. using namespace std;
  3. class Test{
  4. public:
  5. Test(int d = 0):data(d){
  6. cout << "C:" << d << " " << this << endl;
  7. }
  8. //如果参数没有const修饰,下面②处代码编译不过;
  9. Test( Test &t){
  10. cout << "Copy:" << t.data << " " << this << endl;
  11. data = t.data;
  12. }
  13. ~Test(){
  14. cout << "F:" << this->data << "->" << this << endl;
  15. }
  16. int getData()const{
  17. return data;
  18. }
  19. void setData(int d){
  20. data = d;
  21. }
  22. private:
  23. int data;
  24. };
  25. Test fun(Test &x){
  26. int value = x.getData();
  27. Test tmp(value);
  28. return tmp;
  29. }
  30. int main(){
  31. Test t1(100);
  32. //编译器优化了,当把fun(t1)的返回值拷贝给t2时,应该调用拷贝构造函数,但是编译器优化了,就没有调用这次多余的拷贝构造函数,直接把让t2所占用的内存就是右值(fun(t1))所开辟的内存.
  33. const Test& t2 = fun(t1);----->①
  34. //Test t3 = fun(t1); ----->②
  35. //t2.setData(11);
  36. //std::cout << t2.getData() << std::endl;
  37. //Test t2(fun(t1));
  38. return 0;
  39. }

github源代码

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号