zoukankan      html  css  js  c++  java
  • C++返回值的引用与非引用

    转自:

    https://blog.csdn.net/qq_22660775/article/details/89854545

    返回引用与返回非引用的区别:

    返回引用时,函数内部不会构造一个临时变量,而是直接将返回值返回出去。而当为非引用时,会构造一个临时变量(但不一定),然后返回这个匿名的临时变量。

    举例:

    class B {
    public:
    	B(){
    		cout << "B的构造函数" << endl;
    	}
    
    	B(int i){
    		cout << "带int型参数的B的构造函数" << endl;
    	}
    
    	B(const B &ano){
    		cout << "B的拷贝构造函数" << endl;
    	}
    
    	B& operator=(const B& rhs){
    		cout << "B的赋值操作符" << endl;
    		return *this;
    	}
    
    	virtual ~B(){
    		cout << "B的析构函数" << endl;
    	}
    };
    B func2()
    {
    	B b;
    	return b;
    }
    
    int main() {
    
    	B t;
    	t=func2();
         //B z=func2();
    	cout<<endl;
    }
    

      结果为:

     实际上这个过程是:

    首先在main中生成t,调用一个默认构造函数

    然后在func2()中生成一个b,调用一个默认构造函数

    然后要返回b了,使用拷贝构造,利用b拷贝构造一个临时变量tmp

    然后析构b

    然后利用tmp赋值给t

    最后析构这个临时变量tmp

    可以看到,整个过程,由于使用的是非引用,因此会首先调用拷贝构造构造临时变量tmp,然后返回这个tmp

    而当调用B z=func2()时:

     首先进入func2,对b进行构造

    但这里没有构造临时变量,由于外面是B z=func2(),实际上是直接将这个z传入,然后利用b来拷贝构造这个z,最后再析构b

    注意这里析构的顺序,在上面看到,构造完临时变量tmp后,b直接就析构了,然后tmp赋值给t后tmp才析构。注意这里b的析构时间和上一行的析构时间:

    上一行是利用b构造完z后b才析构,也就是说实际上是将这个z当做tmp来拷贝构造。

    而最前面是先拷贝构造tmp,然后b马上析构,最后用tmp来给b赋值。

    也就是说:

    如果返回的是非引用,并不一定会构造一个临时变量。

    如果使用B z=func2()这种方式是不会生成临时变量的;但B b;b=func2();是会生成临时变量的。

     

    想到上次去网易面试时考官问我的一个问题:

    这个返回的ans怎么提高效率?

    如果用引用返回的话则会出问题,因为返回的是局部对象,在赋值的时候实际上已经析构了。

    当时的回答是将结果作为参数放入func()中,也就是改写为void func(vector<int>& result);然后这样就可以提高效率

    但面试官应该想让我get到另外的点

    难道是移动语义或者完美转发?这个我还没看,需要好好研究下。

    vector<int> func()
    {
    	vector<int> ans(2,1);
    
    	return ans;
    }
    

      

  • 相关阅读:
    js 判断字符串中是否包含某个字符串
    MySQL批量更新数据
    js实现字符串切割并转换成对象格式保存到本地
    C#用openfiledialog文件和savefileDialog打开和保存文件
    C#中e.Cancel,e.Handled的区别与应用
    登录窗体与主窗体的关闭
    C#中WinForm程序退出方法技巧总结
    c# 如何获取项目的根目录
    C# Winform中WndProc 函数作用
    SqlDataAdapter.Update批量数据更新
  • 原文地址:https://www.cnblogs.com/lxy-xf/p/11558802.html
Copyright © 2011-2022 走看看