tags:

views:

68

answers:

3

hi,

I have stored instances of class A in a std:vector, vec_A as vec_A.push_back(A(i)). The code is shown below.

Now, I want to store references some of the instances of class A (in vec_A) in another vector or another array. For example, if the A.getNumber() returns 4, 7, 2 , I want to store a pointer to that instance of A in another vector, say std:vector<A*> filtered_A or an array.

Can someone sow me how to do this?? Thanks!

class A {
      public:
             int getNumber();            
             A(int val);
             ~A(){};
      private:
              int num;
};

A::A(int val){
         num = val;
         };

int A::getNumber(){
    return num;
};

int main(){
    int i  =0;
    int num;    
    std::vector<A> vec_A;
    for ( i = 0; i < 10; i++){
        vec_A.push_back(A(i));
        }

    std::cout << "\nPress RETURN to continue...";
    std::cin.get();

    return 0;
}
A: 

You can't store references in STL containers, so you'll have to use pointers:

std::vector<boost::shared_ptr<A> > v1, v2;
boost::shared_ptr<A> p(new A(i));
v1.push_back(p);
v2.push_back(v1.at(0));
Alex - Aotea Studios
@Alex: I am unable to use boost library. Also, A is not created on the heap. It is created as vec_A.push_back(A()). For some reason, I can't change that part of the code.
memC
@memC: you could always use raw pointers, you'll just have to make sure you delete them. Also, shared_ptr is part of tr1, so depending on your compiler you may not need boost. Not sure why you can't create A on the heap.
Alex - Aotea Studios
A: 

I think the safest thing would be to have a second vector that holds indexes into the first vector:

using std::vector;
vector<A> main;
vector<vector<A>::size_type> secondary;

main.push_back(...);
secondary.push_back(main.size() - 1);   // add the index of the last item

Now, to look up an item you take the value in secondary and use that to index into main:

main[secondary[...]];

The reason I recommend this instead of just having secondary store a direct pointer is that every time you add to vector it may need to resize the vector which can invalidate any existing pointers:

using std::vector;
vector<A> vec;
vec.push_back(A());

// get a pointer to the item you just added
A *p0 = &vec[0];

// add another item
a.push_back(A());

// because a push_back() can cause the vector to resize, p0 may no
// longer point to valid memory and cannot safely be dereferenced
R Samuel Klatchko
@RSamuel: I think the choice between holding indexes in the second vector and having pointers in both vectors is down to how these vectors are going to be used. But I agree that having a `vector<A>` and `vector<A*>` is definitely a bad idea.
Alex - Aotea Studios
@RSamuel: However, if the vector shrinks or an item is replaced, your indices could still become invalid. To fix this, make both vectors contain pointers to A. That will make sure your "references" in the second vector don't become invalidated or silently change no matter what happens to the original vector.
Owen S.
@ R Samuel: In my code, I am making sure that the vector is not resized when I create that secondary vector with poiunters to the elements of `main` vector. So, I think even the second example that you illustrate will work in my case.
memC
A: 
int main(){ 
    std::vector<A *> vec_A;
    std::vector<A *> vec_filtered_A;
    // build the first vector : 0..4 repeated once
    for (int i = 0; i < 10; i++){
        vec_A.push_back(new A(i%5));
        }
    // build a vector containing all pointers to objects A where value == 2
    int target = 2;
    for (int i = 0; i < 10; i++){
        if (vec_A[i].getNumber() == 2) {
            // this time it copies pointers
            vec_filtered_A.push_back(vec_A[i]);
            }
        }
    // at this point we have two elements in vec_filtered_A : 
    // vec_filtered_A[0] == vec_A[2]
    // vec_filtered_A[1] == vec_A[7]

    // clean up
    while (~vec_A.empty()) {
        delete vec_A.back();
        vec_A.pop_back();
        }

    return 0;
}
Stéphane