C++返回值的引用与非引用

转自:面试

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

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

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

举例:对象

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;
}

  结果为:blog

 

 实际上这个过程是:get

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

而后在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;
}
相关文章
相关标签/搜索