2010-04-05 58 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); 

请记住,当传递引用时,只要原始容器未被修改,它们可能只有有效。