返回引用和对象遇到的坑

在leet code上做题遇到了一个坑,算法总认为自己写得没有问题,处理流程造就烂熟于心,用X code调试发现还是疏忽了:C++返回引用和返回对象的差别,在一个函数结束的地方返回了一个临时对象的引用!

根据以往的经验,引用是C++程序中高效能的法宝,节省了对象复制拷贝时的开销,但是滥用引用也会导致意想不到的错误。例如以下的代码:

 // 从一个字符串中,从后向前查找一个单词 // @s 源字符串// @index : 查找字符串起始位置的脚标// 返回查找得到的单词,没有找到单词时返回一个含有空字符串的string对象string  findBackWord(string &s,int &index)
    {
        int endPoint = index;
        int startPoint = index;
        int length  = 0;
        int isFirst = 1;
        int i = 0;
        string temp("");

        for( i = index  ; i >=  0;i-- )
        {
            if(isFirst
            && s.at(i) == ‘ ‘)
            {
                continue;
            }
            if(isFirst &&
            s.at(i) != ‘ ‘)
            {
                endPoint = i ;
                isFirst = 0;
            }

            if(!isFirst
            && s.at(i) == ‘ ‘)
            {
                break;
            }
            startPoint = i ;
            length++;
        }
        index = i ;
        if(length)
        {
            temp =  s.substr(startPoint,length);
        }
        return temp;
    }

如果函数的返回类型是引用,则该函数返回的对象始终是一个含有空字符串的string对象!何也?返回的是一个临时对象的引用,在函数返回时,临时对象已经释放,教训啊!

一般来说,返回引用时必须保证在调用函数前,被引用的对象已经存在,也就是说要杜绝返回函数中产生的临时对象的引用。那么问题来了,哪些情况需要返回引用,哪些情况又需要返回对象呢?

如果对象的创建、析构的成本代价很大时,需要考虑采用引用的形式,此时返回值一般是作为函数的输出参数。例如:

void add(string a,string b,string &c)
{
    c = a + b;
}

这只是一个非常简单的例子,目的是说明引用的适用范围。还有一种情况是引用作为返回的类型,常见与一个类的成员函数返回this指针指向的对象引用,代码如下:

A& A::operator =(const A& x)

// do somethin

return *this;

 三、引用总结

  (1)在引用的使用中,单纯给某个变量取个别名是毫无意义的,引用的目的主要用于在函数参数传递中,解决大块数据或对象的传递效率和空间不如意的问题。

  (2)用引用传递函数的参数,能保证参数传递中不产生副本,提高传递的效率,且通过const的使用,保证了引用传递的安全性。

  (3)引用与指针的区别是,指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。

  (4)使用引用的时机。流操作符<<和>>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。

时间: 2024-10-12 19:26:56

返回引用和对象遇到的坑的相关文章

注意不要编写返回引用可变对象的访问器方法

在看<Java核心技术(原书第9版中文版)>的时候,看到113页的一个警告,“注意不要编写返回引用可变对象的访问器方法”.以前没看到过,原来Date对象是可变对象.就可变对象这个概念,查了一下网,我认为可变对象,就是在类中可以不通过域更改器方法就能改变值的对象. 1 package com.csst.sort; 2 3 import java.util.Date; 4 import java.util.GregorianCalendar; 5 6 public class Employee {

函数可以返回一个局部对象,而不能返回一个局部对象的引用(指针):

函数可以返回一个局部对象,而不能返回一个局部对象的引用(指针):当函数返回一个局部对象时,虽然这个对象已经释放,但是返回时会产生一个临时的对象.而当返回一个局部对象的引用时,这个对象已经不存在了.这就要求在函数参数中,包含一个引用或指针.int &func(int a,int b,int &retsult){ retsult = a + b; return &retsult}但是如下代码是错误的(返回局部对象的引用)int &func(int a,int b){ int &

基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------&gt; 可以返回派生类对象的引用或指针

您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. 百度和网页 http://bbs.csdn.net/topics/380238133 的作者无关,不对其内容负责.百度快照谨为网络故障时之索引,不代表被搜索网站的即时页面. 首页 精选版块 移动开发 iOS Android Qt WP 云计算 IaaS Pass/SaaS 分布式计算/Hadoop J

Item 21:需要返回对象时,不要返回引用 Effective C++笔记

Item 21: Don't try to return a reference when you must return an object Item 20中提到,多数情况下传引用比传值更好.追求这一点是好的,但千万别返回空的引用或指针. 一个典型的场景如下: class Rational{ int n, d; public: Raitonal(int numerator=0, int denominator=1); }; // 返回值为什么是const请参考Item 3 friend con

函数绝对的不要返回指向局部对象指针或引用,该返回对象就返回对象。

首先我们来看一个例子: #include <iostream> using namespace std; const int &fun1(int a,int b) { int i=0; i = a + b; return i; } int main() { if (fun1(1, 2) == fun1(2, 5)) { cout << fun1(1, 2) << endl; cout << fun1(2, 5) << endl; cout

c++返回函数局部对象的引用

    函数千万不要返回局部对象的引用或指针 局部变量在函数里面,当函数执行结束后将释放局部变量,如果返回引用或批针这个时候引用或指针指向所指向的内存空间已经释放.指针和引用将是垂悬指针.很危险! 但是如果返回的"局部变量"是堆中的内存值就可以返回了 C++函数为什么要使用引用? C语言之中大量利用指针作为形参或者函数返回值,这是由于值拷贝会有很大的消耗(比如传入传出一个大的结构体).所以在C++之中使用引用作为函数参数和返回值的目的和使用指针是一样的.而且形式上更加直观,所以C++提

返回对象和返回引用

如果方法或函数要返回局部变量,就应该返回引用,而不是指向对象的引用(这里如果返回引用,会因为局部变量被释放,指向一个无意义的对象而出错).在这种情况下,将无可避免地使用复制构造函数来生成返回的对象.如果方法或函数要返回一个没有公有复制构造函数的类(如ostream)的对象,它必须返回一个指向这种对象的引用.最后有些方法和函数(如重载的赋值运算符)可以返回对象,也可以返回指向对象的引用,在这种情况下,应该首选引用,因为它的效率更高. 原文地址:https://www.cnblogs.com/syn

C++基础知识(八)---函数返回值(返回值,返回指针,返回对象,返回引用)---引用---复制构造函数(拷贝构造函数)

一.函数返回值 1.返回值: int test () { int a=1; return a; } 返回值时最简单的方式,它的操作主要在栈上,变量a在函数结束后会删除,为了返回a的值,系统会在内部建立一个临时变量保存a的值,以返回给调用该函数的表达式,调用结束后变量便不再存在.如果a是简单地数据类型也无所谓,不是很占用内存,如果a是大的自定义类型的数据,那么对a的复制将会占用比较大的内存.函数返回值是右值,不能进行运算符操作. 2.返回指针: int *test2() { int *b=new

JavaScript中的this所引用的对象和如何改变这个引用

this是函数内部的一个特殊对象,它引用的是函数执行环境对象.也就是运行是基于函数的执行环境绑定. 1.在网页全局作用域中调用函数时,this引用window var color='black'; function saycolor(){ console.log(this.color); } saycolor();//'black' 第5行函数saycolor在全局作用域调用时this引用的是全局对象window,所以this.color的值就是window.color的值. 2.作为某个对象的