tags:

views:

76

answers:

4

I have a very basic question on returning a reference to an element of a vector .

There is a vector vec that stores instances of class Foo. I want to access an element from this vector . ( don't want to use the vector index) . How should I code the method getFoo here?

#include<vector>
#include<stdio.h>
#include<iostream>
#include<math.h>

using namespace std;
class Foo {      
      public:
             Foo(){};
             ~Foo(){};
};


class B {
      public:
             vector<Foo> vec;
             Foo* getFoo();
             B(){};
             ~B(){};
};


Foo* B::getFoo(){
int i;
vec.push_back(Foo());
i = vec.size() - 1;

// how to return a pointer to vec[i] ??

return vec.at(i);

};

int main(){
    B b;
    b = B();
    int i  = 0;
    for (i = 0; i < 5; i ++){
        b.getFoo();   
        }

    return 0;
}
+2  A: 

Why are you adding a new Foo object in your getFoo() method? Shouldn't you just be retrieving the i'th one?

If so, you can use something like

Foo *getFoo(int i) {
  return &vec[i];  // or .at(i)
}

If you want the last element in the vector, use the back() method.

Alex
Thanks! actually, the method is called when a new Foo needs to be created, and a reference to this new Foo needs to be returned by the method. so the name probably should be create_Foo() or like that. Another Question: Supposee I am returning reference to vec[i], and then the vec is sorted. Will it still return the new elementnt at i (vec[i] ) or it will continue to reference the old element that was at i before sorting?
memC
@memC: It will still point to the same element in the vector, but its value might have changed.
Georg Fritzsche
+1  A: 

Use the back method. You can do return &vec.back();

Naveen
+2  A: 

Why use pointers at all when you can return a reference?

Foo& B::getFoo() {
    vec.push_back(Foo());
    return vec.back();
}

Note that references, pointers and iterators to a vectors contents get invalidated if reallocation occurs.

Also having member data public (like your vec here) isn't good practice - it is better to provide access methods for your class as needed.

Georg Fritzsche
@gf: you wrote: " having member data public (like your vec here) isn't good practice" --> Do you mean declare `vec` as `private`? If so, when I return a reference to an element in `vec` to an outside class, wouldn't it give error?
memC
@memC: Yes, i meant making `vec` private. You can still return references to its contents (or even to the vector itself, although that would defeat the purpose), it just means that a user of the class can't access the member `vec` directly.
Georg Fritzsche
+1  A: 

I'd suggest to use references instead of pointers. Like this

Foo& B::getFoo(){
  vec.push_back(Foo());
  return vec.back();
};

of course, you will also have to change the declaration for getFoo() in your class B:

class B {
      public:
             vector<Foo> vec;
             Foo& getFoo();
};
Michael Ulm