във функция, кое "връщане" би било по-подходящо?
A. vector<Foo>
?
B. shared_ptr<vector<Foor>>
?
С други думи, кое копие е по-малко тежко, какво бихте направили и защо?
във функция, кое "връщане" би било по-подходящо?
A. vector<Foo>
?
B. shared_ptr<vector<Foor>>
?
С други думи, кое копие е по-малко тежко, какво бихте направили и защо?
Мисля, че връщането на shared_ptr<vector<T>>
рядко е полезно. Бих направил това само ако няколко обекта държат споделен вектор, който могат да манипулират. За мен това означава грешка в дизайна. По-добра алтернатива вероятно е връщането чрез const препратка. Това избягва (потенциално скъпа) операция за копиране, но не позволява на инструмента за достъп да променя вектора.
Ако връщате локален std::vector
, можете също да го върнете чрез аргумент.
Ако наистина искате да върнете shared_ptr<vector<T>>
, помислете дали shared_ptr<const vector<T>>
ще свърши работа (векторът може да бъде инспектиран от много хора, но само манипулиран от собственика).
Въпреки това A обикновено е по-скъпо от B, но оптимизациите на възвръщаемата стойност често се прилагат тук. За C++11 std::vector
има конструктор за преместване, който ще гарантира, че връщането на локален std::vector
няма да изисква скъпи операции за копиране.
Запомнете, не оптимизирайте преждевременно :)
Връщането на shared_ptr<vector<Foo>>
гарантира, че няма да се появи допълнително копие.
Връщането на vector<Foo>
може да избегне допълнително копиране, ако се включи оптимизацията на връщаната стойност (RVO) или ако се използва семантика на преместване от C++11. Но ако е важно да избягвам копирането, не бих използвал това (дори ако можете да гарантирате, че тези оптимизации винаги ще бъдат налични), защото не мисля, че е добра идея да се използва семантика за връщане на копие, докато всъщност означава да не копирате .
Вероятно бих избрал едно от тези, но зависи:
vector<Foo>
като параметърback_inserter
).vector
по стойност.
- person hamstergene; 02.11.2011
vector<Foo>
като параметър: Не бих, ако функцията създава вектора вътрешно, тогава това е върната стойност. Конвенцията за извикване за всички компилатори, за които знам, в случай на тип връщане, който не се побира в регистрите, ще приложи това за вас: извикващият разпределя пространството и предава указател към извиквания, след това извикваният инициализира тази памет с реален обект (извикване на подходящия конструктор в зависимост от кода). Ефектът е, че получавате по-чист интерфейс с абсолютно същата цена.
- person David Rodríguez - dribeas; 02.11.2011
В C++03 предпочитайте:
В C++11 предпочитайте:
Ситуацията, в която бихте искали да върнете интелигентен указател с преброени референции, би била, когато множество обекти с различни времена на живот всички ще искат достъп до обекта. Това обаче не е най-честият сценарий, но се случва достатъчно често.
std::move
. Така или иначе е по-добре да използвате elision за копиране.
- person Nicol Bolas; 03.11.2011
unique_ptr
не е опция? Връщането наshared_ptr
предполага, че функцията запазва копие; връщането наunique_ptr
уведомява всички, че собствеността се прехвърля изцяло. - person Nicol Bolas   schedule 02.11.2011