C++函數返回值發生的對象復制


最近用QT做一個監控系統的項目,需要顯示目標的運動軌跡,每次目標移動后,就在目標的軌跡中(用vector記錄)添加一條新軌跡。

但是在運行中畫面里一直不出現軌跡,經過調試發現是記錄軌跡的函數出錯了。

原程序的邏輯是:目標軌跡類是ObjectTrack,通過調用getTrack()函數獲得一個vector,然后將新的坐標append到vector里。

問題出現的原因在於,getTrack()方法返回的vector不是ObjectTrack對象的成員,因為在return的時候發生了vector的復制,所以對復制后的vector添加新坐標是不會被保存的。

解決辦法1:

對返回后的vector進行添加新坐標后再set回ObjectTrack對象中

這個方法會產生額外的vector副本

解決辦法2:

使用引用,將getTrack()函數的返回值設置成引用,並用引用變量接收

不會產生vector的副本,比解決辦法1好

解決辦法3:

在ObjectTrack中添加新的函數用於追加新坐標信息

符合封裝性,使用也更簡單,比1、2好

 

對於C++對象賦值操作(還有return對象)發生的復制現象,做了以下分析:

1.當函數返回值不是引用類型是,會發生復制,且接收函數返回值的變量不能是引用類型

#include <iostream>
using namespace std;

class C1
{
public:
	int a;
	C1(int a){
		this->a = a;
	}
	/*復制構造函數,不修改被拷貝的對象,所以參數為const;參數是引用,
	是因為如果不是引用,在傳遞參數的時候就會被調用復制構造函數,而這
	個函數本身就是復制構造函數,會造成無窮的遞歸調用
	*/
	C1(const C1 &c){
		this->a = c.a;
		cout << "copy constructor called" << endl;
	}
};
class C2
{
public:
	C1 c1;
	C2():c1(10){
	}
	C1 getC1(){
		return c1;
	}
};
int main(){
	C2 c2;
	C1 c1 = c2.getC1();
	cout<<(int)(&c1)<<endl<<(int)(&c2.c1)<<endl;
	return 0;
}

  運行結果是:

copy constructor called
2686712
2686716

 

2.當函數返回值是引用類型,接收函數返回值的變量不是引用時,仍然發生復制

#include <iostream>
using namespace std;

class C1
{
public:
	int a;
	C1(int a){
		this->a = a;
	}
	/*復制構造函數,不修改被拷貝的對象,所以參數為const;參數是引用,
	是因為如果不是引用,在傳遞參數的時候就會被調用復制構造函數,而這
	個函數本身就是復制構造函數,會造成無窮的遞歸調用
	*/
	C1(const C1 &c){
		this->a = c.a;
		cout << "copy constructor called" << endl;
	}
};
class C2
{
public:
	C1 c1;
	C2():c1(10){
	}
	C1 &getC1(){
		return c1;
	}
};
int main(){
	C2 c2;
	C1 c1 = c2.getC1();
	cout<<(int)(&c1)<<endl<<(int)(&c2.c1)<<endl;
	return 0;
}

  運行結果是:

copy constructor called
2686712
2686716

 

3.函數返回值是引用類型,接收函數返回值的變量是引用類型,不會發生復制

#include <iostream>
using namespace std;

class C1
{
public:
	int a;
	C1(int a){
		this->a = a;
	}
	/*復制構造函數,不修改被拷貝的對象,所以參數為const;參數是引用,
	是因為如果不是引用,在傳遞參數的時候就會被調用復制構造函數,而這
	個函數本身就是復制構造函數,會造成無窮的遞歸調用
	*/
	C1(const C1 &c){
		this->a = c.a;
		cout << "copy constructor called" << endl;
	}
};
class C2
{
public:
	C1 c1;
	C2():c1(10){
	}
	C1 &getC1(){
		return c1;
	}
};
int main(){
	C2 c2;
	C1 &c1 = c2.getC1();
	cout<<(int)(&c1)<<endl<<(int)(&c2.c1)<<endl;
	return 0;
}

運行結果是:

2686712

2686712

 

 

另外,數組返回值也會發生復制

String str = strs[i];

str與strs[i]也是不同的對象


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM