2011-02-03 3 views
1

на следующий конструкторестанда :: вектор, Конструкторы, объекты

std::vector<Object> objects(n); 

создает п объекты вызова конструктора по умолчанию, то есть что-то вроде этого:

std::vector <Object> objects; 
for (unsigned int i = 0; i < n; i++) objects.push_back(o); 

Является ли это процедура также действует для динамически выделенных объектов ? Содержит ли конструкция

std::vector<Object *> objects(n); 

представляют эту функциональность?

std::vector <Object*> objects; 
for (unsigned int i = 0; i < n; i++) objects.push_back(new Object()); 

Если нет, можно ли его организовать?

+0

Только для примечания: это что-то вроде этого, за исключением того, что каждый 'push_back()' перераспределяет внутренний буфер вектора. Построение «вектора», передающего количество элементов, выделенных буфером один раз. –

ответ

6
std::vector<Object> objects(n); 

Поведение это зависит от того, какой версии стандарта C++ ваша реализация стандартной библиотеки реализует:

  • В C++ 03, это создает один по умолчанию строится Object, а затем скопировать конструкции, которые возражали n раз.

  • В C++ 0x эта конструкция по умолчанию n Object s.

Разница обычно не имеет значения, но это хорошо знать.


std::vector<Object *> objects(n); 

Это создает vector с п нулем Object* ей в этом. Поскольку Object* не является типом класса и не имеет конструктора, вновь вставленные объекты инициализируются значением, что для указателей означает, что они установлены на NULL.

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

Вы должны использовать смарт-указатель, как shared_ptr или unique_ptr вместо (примечание: auto_ptr смарт-указатель не может храниться в контейнерах из-за его необычной семантики копирования, таким образом shared_ptr или unique_ptr следует использовать).

В любом случае, чтобы вставить указатели на n различных динамически выделенных объектов в контейнер, вам нужно вызвать new n раз, чтобы создать эти n объектов. В вашем решении for нет ничего плохого.

+0

Примером, где это имеет значение, является 'struct dumb {int i; dumb() {static int j = 0; i = j ++; }}; int main (void) {std :: vector v (2); std :: cout << v [1] .i << std :: endl; } ', который будет печатать 0 в C++ 03, но 1 в C++ 0x. –

2

на следующий конструкторе

std::vector<Object> objects(n); 

создает п объекты вызова конструктора по умолчанию

Да, но конструктор по умолчанию используется только для создания второго необязательного параметра к конструктор vector, объекты n в векторе построены путем копирования этого параметра. [C++ 03 ответ]

Если вы сделали что-то вроде:

std::vector<Object*> objects(n, new Object()); 

вы бы динамически выделять один объект и есть n указатели на этот объект в vector, который, вероятно, не то, что вы хотите.

Практически всегда плохая идея использовать контейнер указателей, если этот контейнер должен владеть динамически выделенными объектами. Вы должны рассмотреть что-то вроде boost::ptr_vector, или если это невозможно, контейнер с интеллектуальными указателями (но не std::auto_ptr, хотя).

+0

+1 для комментариев 'ptr_vector' и' auto_ptr'. –

0

Ваш последний пример кода имеет правильную общую идею, но осторожно протектора: vector будет не управлять ассигнованиями для вас, если вы это сделаете! objects.clear() будет утечка памяти, например.

Вместо этого вы, вероятно, захотите использовать std::vector<some_smart_ptr<Object> >, но для выбора правильного класса умных указателей требуется внимание и внимание (например), что происходит при копировании элементов из одного вектора в другой. boost::shared_ptr - это безопасный выбор, но для вашего варианта использования могут возникнуть лишние накладные расходы. boost::ptr_vector может быть лучше.

+0

'vector' вообще не будет выделять выделение, указатели будут инициализированы значением null. –

+0

Пример окончательного кода OP (создание вектора, а затем вызов 'new' и' push_back' в цикле) ясно указывает, что они знают об этом. – zwol

0

Нет, vector не будет автоматически создаваться с указателями на Object экземпляров. Вам нужно будет выполнить цикл for, который вы написали, чтобы правильно его заполнить.

Вам также понадобится delete каждый из этих объектов, когда вы закончите с ними.

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