2010-07-04 2 views
4

Предположим, у меня есть класс FOO.Какая из них лучше?

Я хочу иметь std::vector от FOO.

ли лучше, если я что-то вроде этого:

FOO foo; 
foo.init(); 
foo.prop = 1; 
std::vector<FOO> myvec; 

myvec.push_back(foo); 
foo.prop = 2; 
myvect.push_back(foo); 

или лучше практика, чтобы сделать:

std::vector<FOO> myvec; 
FOO foo; 
myvec.push_back(foo); 
myvec.back().init(); 
myvec.back().prop = 1; 

myvec.push_back(foo); 
myvec.back().init(); 
myvec.back().prop = 2; 

Я в принципе не уверен, что если его лучше сделать модель и толкайте модель вместо того, чтобы делать экземпляр, нажимая его, а затем изменяя его из вектора. Кроме того, какой из них безопаснее и наименее вероятно приведет к утечке памяти?

Благодаря

+5

Почему Foo :: Foo() не вызывает Foo :: init()? Это может помочь, если вы разместите конкретный класс Foo. –

+0

Утечки памяти не будут возникать, если вы не используете новые без удаления. –

ответ

8

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

Я хотел бы дать FOO конструктор, который делает все, что делает init, и устанавливает prop на соответствующее значение. Тогда вы можете просто нажать нужные значения:

myvec.push_back(FOO(1)); 
myvec.push_back(FOO(2)); 
10

Лучшая практика не имеет функции инициализации() - вы хотите конструктор. Если вам всегда нужно установить опору, дайте конструктору параметр для этого. Это не имеет ничего общего с векторами - это способ, которым должен писать весь код на C++.

1

Я думаю, что лучше всего:

myvec.push_back(FOO(1)); 
myvec.push_back(FOO(2)); 
1

Ответ зависит от того, что делает ваш FOO класс. Если это простая структура без указателей и т. Д., То оба подхода подходят друг другу и делают то же самое.

Отметьте, что push_back вставляет копию объекта в вектор. Если ваш класс выделяет память в куче, вам нужен конструктор копирования, который создает глубокую копию ваших объектов, иначе вы получите утечки памяти. Кроме того, если ваши объекты достаточно велики, для создания копий может быть неэффективно. В таких случаях, что я вообще делаю это выделить сам объект в куче извне и вставить указатель на вектор:

std::vector<FOO *> myvec; 
FOO *foo; 

foo = new FOO(); 
foo->init(); 
foo->val = 1; 
myvec.push_back(foo); 

foo = new FOO(); 
foo->init(); 
foo->val = 2; 
myvec.push_back(foo); 

Однако, в этом случае, вы должны помнить, чтобы освободить объекты перед разрушением вектора ,

0

Кроме того, что другие говорили об инициализации ваших объектов в конструкторе, я хотел бы добавить следующее:

В вашем втором примере, где вы положили объекты в векторе, а затем инициализировать их, вы рискуете оставить свой вектор в непригодное состояние.

Если, например, метод init() может генерировать исключение, в вашем векторе вы будете иметь объект с неполностью или частично инициализированным.

Конечно, эти проблемы устраняются конструктором, который гарантирует правильную инициализацию объектов.

В целом: Не начинайте делать вещи с объектами, прежде чем они находятся в пригодном для использования состоянии.