Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ vector pointer/reference problem

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.

like image 483
sub Avatar asked Apr 05 '10 10:04

sub


People also ask

Can vector hold references?

You can't take the address of a reference, since attempting to do so would result in the address of the object being referred to, and thus you can never get a pointer to a reference. std::vector works with pointers to its elements, so the values being stored need to be able to be pointed to.

What is the main issue with storing objects in the vector class as opposed to pointers?

Having vector of objects is much slower than a vector of pointers. The results are because algorithms such as sorting need to move elements inside the container. So they not only read the data but also perform a copy (when the algorithm decides to swap items or move to a correct place according to the order).

Is Pass-by-pointer the same as Pass by reference?

The difference between pass-by-reference and pass-by-pointer is that pointers can be NULL or reassigned whereas references cannot. Use pass-by-pointer if NULL is a valid parameter value or if you want to reassign the pointer. Otherwise, use constant or non-constant references to pass arguments.

Why are pointers used in Passing parameters by reference?

A pointer can receive a NULL parameter, a reference parameter can not. If there's ever a chance that you could want to pass "no object", then use a pointer instead of a reference.


1 Answers

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.
like image 67
Alex Budovski Avatar answered Sep 30 '22 02:09

Alex Budovski