2016-08-23 2 views
11

У меня есть метод фабрики, который создает кучу объектов и возвращает указатели на них. Право собственности на объекты переходит к абоненту:Как вернуть вектор указателей (и собственности) C++ 11

std::vector<animal*> create_zoo(); 

Это работает, но подвержено утечке памяти.

auto zoo = create_zoo(); 

Вектор находится в стеке и автоматически очищается, а содержащиеся объекты - нет.

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

Я думал использовать

std::vector<std::unique_ptr<animal> > create_zoo(); 

но unique_ptr не копировать семантику и я возвращаю vector по значению, которое, теоретически, создает копию.

я мог бы поставить vector на кучу, чтобы избежать этого

std::unique_ptr<std::vector<std::unique_ptr<animal> > > create_zoo(); 

, но это становится смешно.

Это должно работать также:

std::vector<std::shared_ptr<animal> > create_zoo(); 

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

Я открыт для предложений. не обязательно должно быть std::vector. Я просто ищу хороший способ реализации фабрики, которая возвращает право собственности на несколько объектов с современным C++. На данный момент я избегаю повышения. Я пытаюсь изучить новый материал C++ 11.

+0

Вы также можете пересмотреть, нужны ли вам объекты животных, которые будут выделены в качестве указателей. 'std :: vector ' также может работать для ваших целей. Объекты животных будут выделены вектором и будут перемещаться вместе с ним после операций перемещения. –

ответ

13

std::vector<std::unique_ptr<animal>> будет работать нормально: возврат локально-функции приведет к его перемещению, а не копированию (или только если перемещение недоступно).

+0

Хм .. Разве это не означает, что мой код тогда зависит от способности компилятора выполнить «Оптимизацию возвращаемого значения»? Я понимаю, что все соответствующие компиляторы реализовали его, но я не уверен, действительно ли они гарантируют его выполнение во всех ситуациях. Является ли эта стандартная практика? – Stefan

+6

@Stefan нет, это не RVO. RVO полностью удалит функцию-локальную и будет использовать ее на стороне вызывающего абонента на своем месте. это о 'return' move-constructing временном возвращенном объекте (если RVO не удалось заранее). – Quentin

+2

Это немного, что мне не хватало! Возвращение на C++ после 6 лет Python. Я чувствую себя как ржавым, так и испорченным. Продолжаем читать этот материал. благодаря! – Stefan