views:

226

answers:

4

Please take a look at this example:

#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

}

A hell lot of code for an example, I know.

Now so you don't have to spend years thinking about what this [should] do[es]: I have a class myMainContainer which has as its only member an instance of mySubContainer. mySubContainer only has a string val as member.

So I create a vector and fill it with some sample data.

Now, what I want to do is: Iterate through the vector and make a separate function able to modify the current myMainContainer in the vector. However, the vector remains unchanged as the output tells:

0: Value before='foo'
0: Value after='foo'
1: Value before='bar'
1: Value after='bar'
  • What am I doing wrong?

doSomethingWith has to return void, I can't let it return the modified myMainContainer and then just overwrite it in the vector, that's why I tried to pass it by reference as seen in the doSomethingWith definition above.

+10  A: 

You're making a copy of the vector here:

current = vec.at( i );

and modifying current, but printing the original, vec.at(i).

Instead, modify the object directly, e.g.

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

Change it to:

doSomethingWith(vec.at(i));
missingfaktor
A: 

If I understand correctly, what happens is that vector will store copies of your data, not the data directly. I wonder if the answers suggested would be actually useful as the copy of the data would be anyways be made. To make changes to the data, I think you need to do the following. 1. Store the pointer to the object instead of the object directly. 2. Use pointers to get object and make changes to data at the pointer

I think that will solve ur problems.

the100rabh
A: 

Modify the inner loop to not make a copy but use a reference and maintain the reference thus;

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

Bear in mind that when passing around references they are possibly only valid as long as the original container isn't modified.

Richard Harrison