C/C++:使用函数返回的向量的有效方法
作者:互联网
假设我们有一个名为V of vector vector< int>的向量.这是一个班级的私人成员.
我们也有这个类的公共功能:
vector<int> getV(){ return V; }
现在,如果我有这个类的一个实例,我想做的就是读取值并找到向量中所有值的总和,
我可以这样说:
MyClass obj;
//update vector
size_t i, size;
size = obj.getV().size();
int sum = 0;
for(size_t i = 0; i < size; i++){
sum += obj.getV().at(i);
}
或者我可以这样说:
MyClass obj;
//update vector
size_t i, size;
vector<int> myV = obj.getV();
size = myV.size();
int sum = 0;
for(size_t i = 0; i < size; i++){
sum += myV[i];
}
在第二种情况下,我们将整个矢量复制到矢量myV.但是,我不确定在第一种情况下到底发生了什么,我们是否已经使用了矢量,或者每次调用函数getV()时我们是否实际复制了矢量?
如果没有复制,那么我相信第一个版本更有效.
但是,我不是100%究竟发生了什么.
如果我们返回对向量V的引用,我想我们可以完全避免进行任何复制.所以我们可以使用以下函数:
vector<int>* getV { return &V; }
然后
MyClass obj;
//update vector
size_t i, size;
vector<int> * myV = obj.getV();
size = myV->size();
int sum = 0;
for(size_t i = 0; i < size; i++){
sum += myV->at(i);
}
但是我想知道第一种情况到底发生了什么.有没有被复制的东西?即使在第三种情况下,我们返回一个指针,因此会发生某种复制.
先感谢您
解决方法:
原则上,在第一种情况下,您正在接收整个向量的副本,在其上调用size(),然后它立即超出范围.
在实践中,这是如此常见,以至于现代编译器可能能够识别它并完全优化副本. You can read more about this here, for example.知道机器上发生的事情的唯一方法是读取编译的汇编代码.编辑:或者像Named那样进行堆栈跟踪.
标签:c,vector,pass-by-reference,move-semantics,pass-by-value 来源: https://codeday.me/bug/20190831/1779538.html