У меня есть немного вопросов на лучших практиках использования shared_ptr
.
Вопрос 1
Копирует shared_ptr
дешевый? Или я должен передать его как ссылку на мои собственные функции помощника и возврат как значение? Что-то как,
void init_fields(boost::shared_ptr<foo>& /*p_foo*/);
void init_other_fields(boost::shared_ptr<foo>& /*p_foo*/);
boost::shared_ptr<foo> create_foo()
{
boost::shared_ptr<foo> p_foo(new foo);
init_fields(p_foo);
init_other_fields(p_foo);
}
Вопрос 2
Если я использую boost::make_shared
создать a shared_ptr
? Если да, что способствует ему предложения? И как мы можем использовать make_shared
когда T
разве конструктор без параметров не имеет?
Вопрос 3
Как использовать const foo*
? Я нашел два подхода для того, чтобы сделать это.
void take_const_foo(const foo* pfoo)
{
}
int main()
{
boost::shared_ptr<foo> pfoo(new foo);
take_const_foo(pfoo.get());
return 0;
}
ИЛИ
typedef boost::shared_ptr<foo> p_foo;
typedef const boost::shared_ptr<const foo> const_p_foo;
void take_const_foo(const_p_foo pfoo)
{
}
int main()
{
boost::shared_ptr<foo> pfoo(new foo);
take_const_foo(pfoo);
return 0;
}
Вопрос 4
Как я могу возвратить и проверить на NULL
на a shared_ptr
объект? Это - что-то как,
boost::shared_ptr<foo> get_foo()
{
boost::shared_ptr<foo> null_foo;
return null_foo;
}
int main()
{
boost::shared_ptr<foo> f = get_foo();
if(f == NULL)
{
/* .. */
}
return 0;
}
Любая справка была бы большой.
Большинство вопросов были даны ответы, но я не согласен, что копия Shared_PTR дешевле.
Копия имеет различную семантику из передающей передачи. Он изменит ссылочный счетчик, который будет вызвать атомное приращение в лучшем случае и замок в худшем случае. Вы должны решить, какую семантику вам нужно, а затем вы будете знать, передавать ли по ссылке или по стоимости.
С точки зрения производительности, обычно лучше использовать контейнер для уточнения усиления вместо контейнера Shared_PTR.
Копирование дешево, указатель не принимает много места. Вся точка зрения, чтобы сделать его маленьким, чтобы разрешить использование в контейнерах по значению (например, std :: vector
).
make_shared
принимает переменную сумму параметров и предпочтительна механиками на построение его самостоятельно (как make_pair
). Преимущество доступно, особенно если участвует в пребывании временных временных и / или пространств имен:
BOOST :: Const_PTR_CACT Как уже предложено
Smart Picketers имеют перегруженные операторы и могут быть непосредственно использованы в выражениях, оцененных для Bool. Не используйте GOW
. Для всего. Вместо сравнения P.get
p.get
, сравните пустой экземпляр указателя ( my_ptr! = Boost :: shared_ptr
)
ad.2
func_shared( boost::shared_ptr<my_tools::MyLongNamedClass>(
new my_tools::MyLongNamedClass( param1, param2 ) );
против
func_shared( boost::make_shared<my_tools::MyLongNamedClass>( param1, param2 ));
Копирование Shared_PTR теперь стоит 32 байта в стеке Copy и дополнительные сращения / уменьшения RefCount. Решите, дешево это для вас или нет, но не вижу причин, почему не проходить ссылку на постоянную, особенно, что у вас уже есть Typedef для PTR:
void f (const foo_ptr & myfoo)
Особенно учитывая, что стандартные параметры разрешений без записи, проходящие в C ++, является ссылкой Const.
Я бы не имел никаких функций, которые принимают указатель, который не передается. Это похоже (хотя и не идентична) для параметра, проходящей семантику в Java и C #. Зачем погружаться при выборе каждый раз, как пройти объект, вместо того, чтобы иметь один стандартный способ сделать это?
Использование , если (p)
так же, как для обычных указателей. Логическая преобразовательная семантика довольно аккуратная.