2016-11-29 2 views
-3

Я хочу хранить элементы (назовем его E), но я не знаю, что я должен хранить их как объекты или как указатели, указывающие на динамически выделенные объекты.Что лучше: хранить объекты и хранить указатели?

(. А, В, С и т.д. объекты хранить ссылку разыскиваемого Е)

версии A:

E e; 
store.Add(e); //This time the store contains objects. 

В этой версии элемент будет скопирован в но это проще в обращении. (Объекты будут уничтожены, когда родительский объект уничтожается)

версия Б:

E* e = new E(); 
store.Add(*e); //This time the store contains references. 
/*I chose references instead of pointers, 
so I have to use pointers only at allocating and deallocating.*/ 

В этой версии нет копии CONSTR. но мне нужно удалить объекты в деструкторе родительского объекта.

Что лучше и почему? Что может вызвать больше ошибок и что более эффективно?

+1

У вас есть C++ 11? – Danh

+1

Поскольку этот вопрос касается * магазинов *, [обрезка объектов] (http://stackoverflow.com/q/274626/3545273) в стандартных контейнерах также следует заметить. –

ответ

2

В C++ 11 дальше вы также можете просто построить их непосредственно внутри контейнера:

std::vector<Widget> widgets; 
widgets.emplace_back(/*Parameters to construct a widget*/); 

Что лучше и почему?

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

Вы также можете использовать лучшее из обоих миров, вместо этого вместо этого храните интеллектуальные указатели. Таким образом, вы получите полиморфизм, если это потребуется.

std::vector<std::unique_ptr<Widget>> widgets; 
widgets.push_back(std::make_unique<Widget>(/*Parameters to construct a widget*/)); 

Что может вызвать больше ошибок, и который является более эффективным?

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

2

Это зависит от того, как вы используете свой магазин. Хранение объектов означает, что вы скопируете их при вызове Add, а также при копировании магазина (среди других обстоятельств): это может стоить и может привести к нежелательному поведению.

Указатели могут быть хорошей альтернативой, но тогда вам следует использовать управляемые указатели, такие как std::unique_ptr, поэтому вам не придется обрабатывать удаление.

версия C:

auto e = std::unique_ptr<E>(new E()); 
store.Add(e); //This time the store contains managed pointers. 

Вы также можете использовать std::make_unique если у вас есть C++ 14 доступны.

версия C-бис:

auto e = std::make_unique<E>(); 
store.Add(e); //This time the store contains managed pointers. 

Другой вариант, если вам нужно разделить острые предметы могут быть использовать std::shared_ptr, но использовать его только если это необходимо.

версия D:

auto e = std::make_shared<E>(); 
store.Add(e); //This time the store contains shared managed pointers. 
Смежные вопросы