2012-12-06 39 views
0

在此代碼中是否存在任何潛在危險?在函數內部創建一個局部矢量,然後將其作爲參考傳遞給將其存儲爲參考的其他函數

void f(){ 
    std::vector<int> v; 
    ... 
    g(v); 
} 

void g(std::vector<int> &a){ 
    ... //store a by reference in variable blah (global) 
} 

當f()的調用完成時,v被銷燬,但是等等仍然會引用v。請問blah會失效嗎?有沒有更好的方法來做到這一點,而不是不必要的矢量副本?

+0

你可以移動它。 – chris

回答

3

除了詹姆斯給出了答案,還有第三種可能性,具有相同可讀性不晃來晃去參考您的第一個想法,沒有載體本身的堆分配,沒有不必要的副本:

std::vector<int> global; //somewehere - you don't have it really global, do you? 

void f() { 
    std::vector<int> vf; 
    /* ... */ 
    g(std::move(vf)); 
} 

void g(std::vector<int> vg) //by value! 
{ 
    /* ... */ 
    global.swap(vg); 
} 

既然你移動vf「出」 f()vg的舉動,構造函數被調用,這意味着它只是需要以前vf擁有的資源的所有權,所以沒有不必要的複製和分配製成。如果global在呼叫g()(以及f())之前存在,則swap()僅在g()中有效。你說過要將矢量存儲在一個引用中,所以我假設g()實際上創建了存儲對象,並且在調用之前沒有global。然後,而不是與現有對象交換vg應通過std::move傳遞給存儲對象。

在總,你又真的只能創建一個矢量(vf),所有的人實際上是一樣的,move d從原來的,所以你有基本相同的性能,通過引用傳遞,但沒有懸掛裁判。

(對於nitpickers:是的,移動向量是不是傳遞一個引用,典型的複製和清零三分,而不是照搬一個多一點,但它確實沒有什麼比堆分配,載體拷貝等)。

0

是的,有你描述的問題。無論是在堆上

void f() 
{ 
    std::vector<int>* v = new std::vector<int>(); 
    // ... 
    g(v); 
} 

void g(std::vector<int>* a) 
{ 
    // Store in blah 
    // But don't forget to delete it. 
} 

創建v還是有它從一開始就一個全球性的。

std::vector<int> v; 

void f() 
{ 
    g(); 
} 

void g() 
{ 
    // Use v; 
} 
相關問題