2015-03-14 3 views
2

Что более часто встречается в вашем опыте: func1() или funct2()? Предположим, что func1 и func2 лучше не как метод класса Foo.Передача unique_ptr vs raw_ptr?

void func1(unique_ptr<Bar>& bar) { /* alter pointed to object's attributes */ } 

void func2(Bar* const bar) { /* alter pointed to object's attributes */ } 

class Foo 
{ 
    unique_ptr<Bar> bar; 
    void mutate_bar1(){ func1(bar); } 
    void mutate_bar2(){ func2(bar.get()); } 
} 

ответ

5

GotW #91 Solution: Smart Pointer Parameters От:

Рекомендации: Не передавайте смарт-указатель в качестве параметра функции, если вы не хотите использовать или манипулировать сам смарт-указатель, например, для обмена или передачи права собственности.

Руководство: Предпочитают передача объектов по значению, * или &, а не смарт-указатель.


Как обычно, используйте *, если вам нужно, чтобы выразить нулевой (не виджет), в противном случае предпочитает использовать &; и если объект введен только для ввода, напишите const widget* или const widget&.

1

Лично я хотел бы пойти с mutate_bar2(). Вы правильно управляете жизненным циклом своего указателя, сохраняя его в элементе класса std::unique_ptr. Поэтому вам не нужно беспокоиться о утечке памяти. Вы можете безопасно использовать необработанный указатель. Я не вижу никакого преимущества в прохождении вокруг std::unique_ptr, и это, вероятно, немного медленнее для доступа.

+0

Это предполагает, конечно, что «изменение атрибутов» не требует ссылки на «бар» дольше, чем продолжительность функции (что в данном случае, вероятно, является разумным допущением). Если это так, вы, вероятно, не должны использовать 'unique_ptr' в первую очередь, если вы не собираетесь передавать право собственности на' std :: move() 'или что-то еще. – Kevin

+1

@Kevin Точно. Если вы хотите, чтобы указатель выходил из-живого объекта, то сначала нужно начинать с 'std :: unique_ptr'. Вот почему я не вижу преимуществ, связанных с 'std :: unique_ptr'. – Galik