2012-02-09 2 views
4

Я начинаю с C++ и у меня есть сомнения:Указатель и векторы в C++

Я делаю функцию, которая будет возвращать вектор объектов класса MyClass.

vector<MyClass>* myMethod() 

Первый вопрос: правильно ли вернуть указатель?

Второй вопрос: если я собираюсь вернуть указатель, должен ли я также вставлять указатель объекта MyClass в вектор?

MyClass* object; 
myVector.push_back(*object); 
+0

'Я делаю функцию, которая будет возвращать вектор объектов класса MyClass' Нет, это не так. Вы возвращаете указатель. –

+0

'правильно вернуть указатель? Это зависит от многих, многих вещей. –

+0

В вашем примере кода (a) используется недопустимый указатель и недействительный разыменование указанного недопустимого указателя; (b) не имеет смысла, потому что вы не вставляете указатель в вектор вообще –

ответ

6

Нет ничего плохого в методе, который возвращает указатель на вектор: vector<MyClass>* myMethod(). Но вы должны задать себе несколько вопросов, например:

  1. Следует ли указывать вектор? Разве это не может быть vector<MyClass>?
  2. Если этот метод также выделяет память для этого вектора?
  3. Должно ли вызывающее устройство этого метода delete/free этой памяти?

А ваш второй вопрос: я бы вектор указателей на объекты MyClass (vector<MyClass*>) только тогда, когда это действительно необходимо. Это вызовет некоторые проблемы с управлением памятью, поэтому давайте выбираем более простой способ.

Хорошо, давайте поговорим об этом вопросе: Должен ли этот метод также выделять память для этого вектора?
Если цель этого метода состоит в том создать вектор, то да, метод должен также выделять для него память:

vector<MyClass>* myMethod() 
{ 
    vector<MyClass>* v = new vector<MyClass>; 
    // initialize, fill or do whatever with this vector 
    return v; 
} 

абонент должен очистить то:

vector<MyClass>* v = myMethod(); 
    // do some stuff 
    delete v; // clean up 

Если целью является только получение указателя на определенный вектор, который не может быть получен вызывающим абонентом, он может выглядеть так:

vector<MyClass> _x; // caller can not access _x but myMethod can 

vector<MyClass>* myMethod() 
{ 
    return &_x; 
} 

абонент не должен удалить этот вектор в этом случае:

vector<MyClass>* v = myMethod(); 
    // do some stuff, don't delete v 
+0

Вопрос 2: способ автоматически распределяет память для меня, если я возвращаю указатель на вектор? Если я не буду возвращать указатель, когда вектор будет удален из памяти? Благодаря! – Maverik

+1

@ lucaghera: Я отредактировал свой ответ. – LihO

+0

Последний вопрос;) Это если я не верну указатель, если я выделил память? ('vector * v = новый вектор ') – Maverik

5

В C++ 11, вы можете просто вернуть std::vector<T>, и это будет быстро. Нет временных бесполезно, так как std::vector поддерживает move-semantic, что означает, что ресурсы, выделенные для временных, будут украдены семантическими функциями move.

И если ваш тип T управляет ресурсами, то вам также следует реализовать семантику движения, а также обычную семантику копирования.

+3

И даже без C++ 11 возвращение 'std :: vector ' часто будет в порядке. RVO существует задолго до 2011 года. – kennytm

+0

@KennyTM: RVO не гарантируется во всех случаях. – Nawaz

+3

@Nawaz: автоматические переходы из локальных переменных возникают только в том случае, если критерии для элиминации копии выполняются в первую очередь. –

8

Вектор может быть вектором объектов или вектором указателей. Это полностью не зависит от того, есть ли у вас вектор или указатель на вектор.

Если вы начинаете с C++, старайтесь избегать указателей. Просто верните вектор объектов. Помните, что вектор содержит его содержимое. Когда вы помещаете объект в вектор, он будет скопирован.

+0

Спасибо, косить мой вопрос: когда вы предлагаете мне использовать указатели для вектора? – Maverik

+1

+1 «Не использовать голые указатели» не может быть достаточно напряженным. –

1

Да, вы можете вернуть указатель на вектор, и это означает, что вы хотите иметь возможность изменять этот вектор. Просто имейте в виду, что вы не должны возвращать указатель на локальную переменную.

Что касается прокрутки указателей в векторе - это зависит от того, что вы хотите сделать, но вы НЕ ДОЛЖНЫ нажать пуансоны.

Смежные вопросы