C++ —— 非常量引用不能指向临时对象

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

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

如以下情况就会出现:

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

    Rational a(4,5);
    Rational b(1,3);
    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++语言规范没规定编译器生成临时变量的规则,程序员无法得知由编译器生成的临时变量的名字,程序员无法访问那个临时变量。这意味着,以引用的方式传递一个临时变量做为函数参数,如果函数内部对此临时变量做了修改,那么函数返回后,程序员无法获得函数对临时变量的修改。函数对临时变量所做出的所有更改,都将丢失。
一方面,在函数申明中,使用非常量型的引用告诉编译器你需要得到函数对某个对象的修改结果,可是你自己又不给变量起名字,直接丢弃了函数的修改结果,编译器只能说:“大哥,你这是干啥呢,告诉我把结果给你,等我把结果给你了,你又直接给扔了,你这不是在玩我吗?” [1]

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

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

改为值传递:

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

改为常量引用:

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

 

posted @ 2016-03-02 13:20  BensonLaur  阅读(3031)  评论(0编辑  收藏  举报