C ++: переход на unique_ptr - PullRequest
       10

C ++: переход на unique_ptr

2 голосов
/ 30 января 2020

Моя проблема в том, что я разработчик внешнего интерфейса, но мне нужно добавить изменения в проект C ++.

Как это было:

std::vector<myObject*> myArray;
...
myArray.push_back(new myObject);
...
myArray.back();

Как я пытаюсь это изменить:

std::vector<std::unique_ptr<myObject>> myArray;
...
myArray.push_back(std::unique_ptr<myObject> (new myObject));
...
myArray.back().get(); // this place looks not good in my opinion :)

Многие функции должны получить myObject*. И я не знаю, сколько будет изменений, если я изменю параметры функции.

Не могли бы вы посоветовать, как правильно получить указатель в этом случае?

1 Ответ

9 голосов
/ 30 января 2020

Как уже упоминалось в комментариях, вы должны использовать

myArray.push_back(std::make_unique<myObject>());

(или emplace_back вместо push_back) вместо new. По возможности следует избегать прямого использования new.


Вам не нужно часто звонить .get() на std::unqiue_ptr.

Вы можете получить ссылку к хранимому объекту с помощью *:

auto& reference_to_object = *myArray.back();

Вы можете получить доступ к членам напрямую через ->:

myArray.back()->some_function();

Только если вам нужен не владеющий указатель (который должен быть гораздо реже, чем ссылка) вам нужно позвонить .get():

auto ptr_to_object = myArray.back().get();

или вы можете использовать

auto ptr_to_object = &*myArray.back();

для этого (за исключением очень маловероятного случая, когда operator& перегружен для myObject).


Я думаю, проблема в том, что, как вы говорите, " Многие функции должны получить myObject*". Это должно быть гораздо реже, чем кажется. Только функции, которые также принимают нулевой указатель в качестве аргумента, должны принимать указатели в качестве параметра. В противном случае ссылки должны быть предпочтительными. Первое происходит не так часто.


Также обратите внимание, что у вас действительно должна быть веская причина использовать (умные) указатели внутри std::vector. Есть несколько причин не просто использовать std::vector<myObject>, например, myObject не является подвижным, очень дорогим для перемещения, myObject используется полиморфно или ссылки на содержащиеся объекты должны быть недействительными при добавлении элементов / удален. (Хотя std::list может работать лучше в последнем случае.) Если ни одна из этих или другие причины, которые я забыл упомянуть, применимы, просто используйте std::vector<myObject>.

...