2010-04-26 5 views
4

У меня есть очень простой вопрос о возврате ссылки на элемент вектора.Возврат указателя на объект в std :: vector

Существует вектор vec, в котором хранятся экземпляры класса Foo. Я хочу получить доступ к элементу из этого вектора. (не хотите использовать векторный индекс). Как мне закодировать метод getFoo здесь?

#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

Зачем использовать указатели вообще, когда вы можете вернуть ссылку?

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

Обратите внимание, что ссылки, указатели и итераторы vector сек содержания получают недействительные, если происходит перераспределение.

Кроме того, наличие данных о членах общественности (например, ваш vec) не является хорошей практикой - лучше предоставить методы доступа для вашего класса по мере необходимости.

+0

@gf: Вы писали: «Имея данные участника публично (например, ваш vec здесь), не является хорошей практикой» -> Вы имеете в виду declare 'vec' как' private'? Если это так, когда я возвращаю ссылку на элемент в 'vec' внешнему классу, не выдаст ли он ошибку? – memC

+0

@memC: Да, я хотел сделать 'vec' приватным. Вы все равно можете возвращать ссылки на его содержимое (или даже на сам вектор, хотя это может превзойти цель), это просто означает, что пользователь класса не может напрямую обращаться к элементу 'vec'. –

2

Почему вы добавляете новый объект Foo в свой метод getFoo()? Разве вы не должны просто искать i-го?

Если да, то вы можете использовать что-то вроде

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

Если вы хотите, последний элемент в векторе, используйте метод back().

+0

Спасибо! на самом деле, метод вызывается, когда необходимо создать новый Foo, и ссылка на этот новый Foo должна быть возвращена методом. поэтому имя, вероятно, должно быть create_Foo() или тому подобное. Другой вопрос: Предположим, я возвращаю ссылку на vec [i], а затем vec сортируется. Будет ли он по-прежнему возвращать новый элементnt в i (vec [i]) или он будет продолжать ссылаться на старый элемент, который был в i перед сортировкой? – memC

+0

@memC: он все равно укажет на тот же элемент в векторе, но его значение может измениться. –

1

Используйте метод back. Вы можете сделать возврат &vec.back();

1

Я предлагаю использовать ссылки вместо указателей. Как это

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

конечно, вы также должны изменить объявление для getFoo() в вашем классе B:

class B { 
     public: 
      vector<Foo> vec; 
      Foo& getFoo(); 
}; 
Смежные вопросы