2010-04-05 90 views
5

請看看這個例子:C++向量指針/引用問題

#include <iostream> 
#include <vector> 
#include <string> 
using namespace std; 

class mySubContainer 
{ 
public: 
    string val; 
}; 

class myMainContainer 
{ 
public: 
    mySubContainer sub; 
}; 

void doSomethingWith(myMainContainer &container) 
{ 
    container.sub.val = "I was modified"; 
} 

int main() 
{ 
    vector<myMainContainer> vec; 


    /** 
    * Add test data 
    */ 
    myMainContainer tempInst; 

    tempInst.sub.val = "foo"; 
    vec.push_back(tempInst); 

    tempInst.sub.val = "bar"; 
    vec.push_back(tempInst); 


    // 1000 lines of random code here 

    int i; 
    int size = vec.size(); 
    myMainContainer current; 

    for(i = 0; i < size; i ++) 
    { 
     cout << i << ": Value before='" << vec.at(i).sub.val << "'" << endl; 

     current = vec.at(i); 
     doSomethingWith(current); 

     cout << i << ": Value after='" << vec.at(i).sub.val << "'" << endl; 
    } 
    system("pause");//i suck 

} 

甲地獄大量的代碼爲一個例子,我知道。

現在,您不必花費多年的時間考慮這個[應該]做什麼[es]:我有一個班級myMainContainer,其中有一個mySubContainer的實例。 mySubContainer只有一個字符串val作爲成員。

因此,我創建一個向量並填充一些示例數據。

現在,我想要做的是:遍歷向量並創建一個單獨的函數,以便能夠修改向量中的當前myMainContainer。但是,向量保持不變的輸出告訴:

0: Value before='foo' 
0: Value after='foo' 
1: Value before='bar' 
1: Value after='bar' 
  • 我在做什麼錯?

doSomethingWith必須返回void,我不能讓它返回修改後的myMainContainer,然後就覆蓋它的載體,這就是爲什麼我試圖通過參考上文中doSomethingWith定義視爲通過。

回答

11

你讓這裏的載體的拷貝:

current = vec.at(i); 

和修改current,但打印原來,vec.at(i)

而是直接修改對象,例如,

doSomethingWith(vec[i]); // or vec.at(i) for checked access. 
1
current = vec.at(i); 
doSomethingWith(current); 

將其更改爲:

doSomethingWith(vec.at(i)); 
0

如果我理解正確的,什麼情況是,載體將直接存儲數據,而不是數據的副本。我不知道所提出的答案是否真的有用,因爲無論如何都會做出數據的副本。要更改數據,我認爲您需要執行以下操作。 1.將指針直接存儲到對象而不是對象。 2.使用指針獲取對象並在指針處更改數據

我認爲這樣可以解決您的問題。

2

將內部循環修改爲不復制,但使用引用並維護引用;

myMainContainer &current = vec[ i ]; 
doSomethingWith(current); 

請記住,當傳遞引用時,只要原始容器未被修改,它們可能只有有效。