目录
  1. 举例
  2. 分析
  3. 解决
1、举例

非常量引用 指向 临时对象 —— 即:将 临时对象 传递给 非常量引用类型。

如以下情况就会出现:

实现实数Rational类,实数可以使用+号相加,运算的结果要可以使用 "cout << " 以分数形式输出 实数Rational 的值:

    Rational a(,);
Rational b(,);
cout << a+b << endl;

在这里需要重载2个操作符函数:“+”号 和  “<<” 输出符号

//在Rational类中定义如下
friend ostream &operator<< (ostream& outs,Rational &rational);
Rational operator+(Rational &secondRational);

在这种定义下,就会出现我们所要说的问题:非常量引用不能指向临时对象。

a+b 函数返回一个Rational类的临时对象;而 << 操作函数的参数却是 Rational & rational 。这种情况函数会报错如下:

    no match for 'operator<<' in 'std::cout << a.Rational::operator+(((Rational&)(& b)))'

虽然定义了 operator<< 。但是编译器对 a+b 返回的临时对象不买单,直接报了个“没有匹配的函数” 的错误。

2、分析

以C++的语义来说,如果一个程序员只想传递参数给函数,而不希望函数修改传入的参数时,那么,或者使用值传递,或者采用常量型引用。考虑到大对象复制时产生的开销,一般使用常量型引用const &。如果函数的参数是某个类型的一个非常量的引用,那就相当于告诉编译器,程序员希望得到函数对参数的修改结果。
临时变量是由编译器生成的,C++语言规范没规定编译器生成临时变量的规则,程序员无法得知由编译器生成的临时变量的名字,程序员无法访问那个临时变量。这意味着,以引用的方式传递一个临时变量做为函数参数,如果函数内部对此临时变量做了修改,那么函数返回后,程序员无法获得函数对临时变量的修改。函数对临时变量所做出的所有更改,都将丢失。
一方面,在函数申明中,使用非常量型的引用告诉编译器你需要得到函数对某个对象的修改结果,可是你自己又不给变量起名字,直接丢弃了函数的修改结果,编译器只能说:“大哥,你这是干啥呢,告诉我把结果给你,等我把结果给你了,你又直接给扔了,你这不是在玩我吗?”

同时,C++的标准 为了防止给常量或临时变量(只有瞬间的生命周期)赋值(易产生bug),只许使用const引用之。

3、解决
friend ostream &operator<< (ostream& outs,Rational &rational);  //非常量引用

改为值传递:

ostream &operator<<(ostream &outs, Rational ratiaonl)       //值传递

改为常量引用:

ostream &operator<<(ostream &outs,const Rational &rational) //常量引用

C++ —— 非常量引用不能指向临时对象的更多相关文章

  1. 非const引用不能指向临时变量

    没找到具体原因,MSDN看到下面这句,VC是从2008才有这一限制的,感觉就是从语法上对临时变量增加了限定,因为一般说来修改一个临时变量是毫无意义的,通过增加限定,强调临时变量只读语义.虽然实际上修改 ...

  2. C++ 非常量引用无效

    /* 非常量引用无效 */ #include <iostream> using namespace std; /* C++标准的规定:非常量的引用不能指向临时对象: 为了防止给常量或临时变 ...

  3. c++产生非常量引用的初始值必须是左值

    出现这种情况是因为调用函数的形参类型是  T&(T为某一类型),该类型与调用参数值传入不一致,比如函数中形参是int型,而传入实参是double,存在隐式类型转化,系统会自动产生临时变量tem ...

  4. Python3标准库:weakref对象的非永久引用

    1. weakref对象的非永久引用 weakref模块支持对象的弱引用.正常的引用会增加对象的引用数,并避免它被垃圾回收.但结果并不总是如期望中的那样,比如有时可能会出现一个循环引用,或者有时需要内 ...

  5. 常量函数、常量引用参数、常量引用返回值[C++]

    1. 关于常量引用正像在C语言中使用指针一样,C++中通常使用引用 有一个函数... foo()并且这个函数返回一个引用...... & foo()...., 一个指向位图(Bitmap)的引 ...

  6. 临时对象与NRV技术

    <More Effective C++>中讲到,在C++中真正的临时对象是看不见的,它们不出现在你的源代码中.建立一个没有命名的非堆(non-heap)对象会产生临时对象,这种未命名的对象 ...

  7. C++临时对象的生命期

    class Test{ public: Test(int a):m_int(a){ printf("this is Test(%d) ctor\n", m_int); } ~Tes ...

  8. 非const引用参数传入不同类型编译不过的理解(拒绝将临时对象绑定为非const的引用的形参是有道理的)

    int f (int & I) { cout<<I<<std::endl; } void main() { long L; f(L); // 编译不过 f((int)L ...

  9. 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象, const 指针和指向 const 对象的指针, const 对象的引用

    [源码下载] 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象,  const 指针和指向 const 对象的指针, con ...

随机推荐

  1. OD: Kernel Vulnerabilities Analyze

    内核漏洞大多出没于 ring3 到 ring0 的交互中.从 ring3 进入 ring0 的通道,以及操作系统提供的 API 都有可能存在漏洞.例如:驱动程序中 IoControl 的处理函数,SS ...

  2. iOS横竖屏切换的一些坑(持续更新)

    最近在做视频类的App,遇到视频滚动播放的坑,紧接着就是横竖屏问题.之前太过天真不想做横竖屏配置.只是想旋转视频View,但是分享什么的包括AlertView还是竖屏样式,项目着急上线(1周提交一次也 ...

  3. MySQL 查询数据

    MySQL 查询数据 MySQL 数据库使用SQL SELECT语句来查询数据. 你可以通过 mysql> 命令提示窗口中在数据库中查询数据,或者通过PHP脚本来查询数据. 语法 以下为在MyS ...

  4. ubuntu远程连接

     apt-cache search openssh-server   //直接用apt-get install openssh-server安装.记不清包名字时可用apt-cache search o ...

  5. 在SpringMVC框架下建立Web项目时web.xml到底该写些什么呢?

    刚刚初学Spring MVC,却连一个简单的helloworld都搞的懵懵懂懂的,配置文件搞不清,各种文件之间的逻辑关系也不懂,连续看了好些日子的Spring MVC了,今天终于下定决心,每天记录一点 ...

  6. Wireshark抓包、过滤器

    查阅于http://blog.sina.com.cn/s/blog_5d527ff00100dwph.html 1.捕捉过滤器 设置捕捉过滤器的步骤是:- 选择 capture -> optio ...

  7. TalkingData游戏版本在Cocos2d-x 3.0使用

    Cocos2dx在3.0的版本中改动确实不少啊,所以导致原来可以在Cocos2.x版本上的demo都不能直接用,所以不得不重要写一个新的demo 但是TalkingData的库一直都是可以用的,只是之 ...

  8. js实现输入验证码

    html部分: <div> <input type="text" id="input" /> <input type=" ...

  9. 142 Linked List Cycle II(如果链表有环,找到入口结点Medium)

    题目意思:如果有环,返回入口结点 思路:先判断有没环,再计算环的结点数,然后p1指向头,p2往后移结点次数,p1.p2相遇为入口结点 ps:还是利用指针间距这个思路 /** * Definition ...

  10. Nginx源码研究八:nginx监听socket实现流程

    前面描述了nginx系统分析nginx的配置文件,初始化模块相关参数的过程,这里利用nginx监听socket的实现过程,做一次完整的回顾 1.首先,nginx启动的main函数中,会先初始化cycl ...