Chcę przekazać wspólny wskaźnik do funkcji. Czy możesz mi z tym pomóc?
Jasne, mogę ci w tym pomóc. Zakładam, że rozumiesz semantykę własności w C ++. Czy to prawda?
Tak, ten temat jest mi dość wygodny.
Dobry.
Ok, przychodzą mi do głowy tylko dwa powody, dla których warto się shared_ptr
kłócić:
- Funkcja chce współdzielić własność obiektu;
- Funkcja wykonuje pewną operację, która działa specjalnie na
shared_ptr
s.
Który Cię interesuje?
Szukam ogólnej odpowiedzi, więc właściwie jestem zainteresowany obydwoma. Jestem jednak ciekawy, co masz na myśli w przypadku nr 2.
Przykładami takich funkcji są std::static_pointer_cast
komparatory niestandardowe lub predykaty. Na przykład, jeśli chcesz znaleźć wszystkie unikalne shared_ptr z wektora, potrzebujesz takiego predykatu.
Ach, kiedy funkcja faktycznie musi manipulować samym inteligentnym wskaźnikiem.
Dokładnie.
W takim przypadku uważam, że powinniśmy przejść przez odniesienie.
Tak. A jeśli to nie zmieni wskaźnika, chcesz przejść przez odwołanie do stałej. Nie ma potrzeby kopiowania, ponieważ nie musisz dzielić się własnością. To jest inny scenariusz.
Ok, rozumiem. Porozmawiajmy o innym scenariuszu.
Ten, w którym jesteś współwłasnością? Ok. W jaki sposób dzielisz się własnością shared_ptr
?
Kopiując to.
Wtedy funkcja będzie musiała wykonać kopię shared_ptr
, prawda?
Oczywiście. Więc przekazuję to przez odniesienie do stałej i kopiuję do zmiennej lokalnej?
Nie, to pesymizacja. Jeśli zostanie przekazany przez odniesienie, funkcja nie będzie miała innego wyboru, jak tylko wykonać kopię ręcznie. Jeśli zostanie przekazana przez wartość, kompilator wybierze najlepszy wybór między kopiowaniem a przeniesieniem i wykona go automatycznie. Więc podaj wartość.
Słuszna uwaga. Muszę częściej pamiętać ten artykuł „ Chcesz szybkości? Przekaż wartość ”.
Czekaj, co jeśli funkcja na przykład przechowuje shared_ptr
zmienną składową? Czy to nie spowoduje zbędnej kopii?
Funkcja może po prostu przenieść shared_ptr
argument do swojej pamięci. Przeniesienie a shared_ptr
jest tanie, ponieważ nie zmienia liczby odniesień.
Ach, dobry pomysł.
Ale myślę o trzecim scenariuszu: co jeśli nie chcesz manipulować shared_ptr
ani dzielić się własnością?
W takim przypadku shared_ptr
jest całkowicie bez znaczenia dla funkcji. Jeśli chcesz manipulować wskazanym, weź go i pozwól dzwoniącym wybrać, jakiej semantyki własności chcą.
I czy powinienem traktować wskazanego przez odniesienie czy według wartości?
Obowiązują standardowe zasady. Inteligentne wskazówki niczego nie zmieniają.
Przekaż wartość, jeśli mam zamiar kopiować, przekaż przez odniesienie, jeśli chcę uniknąć kopiowania.
Dobrze.
Hmm. Myślę, że zapomniałeś o innym scenariuszu. A jeśli chcę dzielić się własnością, ale tylko pod pewnymi warunkami?
Ach, ciekawy skrajny przypadek. Nie spodziewam się, że zdarzy się to często. Ale kiedy to się stanie, możesz albo przekazać wartość i zignorować kopię, jeśli jej nie potrzebujesz, albo przekazać przez odniesienie i utworzyć kopię, jeśli jej potrzebujesz.
Ryzykuję jedną zbędną kopię w pierwszej opcji i tracę potencjalny ruch w drugiej. Nie mogę zjeść ciasta i też go mieć?
Jeśli jesteś w sytuacji, w której to naprawdę ma znaczenie, możesz zapewnić dwa przeciążenia, jedno pobierające odwołanie do stałej lwartości, a drugie pobierające odwołanie do wartości r. Jedna kopia, druga się porusza. Szablon funkcji doskonałego przekazywania to kolejna opcja.
Myślę, że obejmuje to wszystkie możliwe scenariusze. Dziękuję Ci bardzo.
const std::shared_ptr<myClass>& arg1