Вопросы на использованиях shared_ptr - C++

У меня есть немного вопросов на лучших практиках использования 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;
}

Любая справка была бы большой.

17
задан Navaneeth K N 27 January 2010 в 05:46
поделиться

5 ответов

Большинство вопросов были даны ответы, но я не согласен, что копия Shared_PTR дешевле.

Копия имеет различную семантику из передающей передачи. Он изменит ссылочный счетчик, который будет вызвать атомное приращение в лучшем случае и замок в худшем случае. Вы должны решить, какую семантику вам нужно, а затем вы будете знать, передавать ли по ссылке или по стоимости.

С точки зрения производительности, обычно лучше использовать контейнер для уточнения усиления вместо контейнера Shared_PTR.

8
ответ дан 30 November 2019 в 13:45
поделиться
  1. Копирование дешево, указатель не принимает много места. Вся точка зрения, чтобы сделать его маленьким, чтобы разрешить использование в контейнерах по значению (например, std :: vector > ).

  2. make_shared принимает переменную сумму параметров и предпочтительна механиками на построение его самостоятельно (как make_pair ). Преимущество доступно, особенно если участвует в пребывании временных временных и / или пространств имен:

  3. BOOST :: Const_PTR_CACT Как уже предложено

  4. 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 ));
4
ответ дан 30 November 2019 в 13:45
поделиться
  1. Копирование Shared_PTR теперь стоит 32 байта в стеке Copy и дополнительные сращения / уменьшения RefCount. Решите, дешево это для вас или нет, но не вижу причин, почему не проходить ссылку на постоянную, особенно, что у вас уже есть Typedef для PTR: void f (const foo_ptr & myfoo) Особенно учитывая, что стандартные параметры разрешений без записи, проходящие в C ++, является ссылкой Const.

  2. Я бы не имел никаких функций, которые принимают указатель, который не передается. Это похоже (хотя и не идентична) для параметра, проходящей семантику в Java и C #. Зачем погружаться при выборе каждый раз, как пройти объект, вместо того, чтобы иметь один стандартный способ сделать это?

  3. Использование , если (p) так же, как для обычных указателей. Логическая преобразовательная семантика довольно аккуратная.

3
ответ дан 30 November 2019 в 13:45
поделиться
  1. Да, копия абсолютно дешевая. Помимо проведения указателя, есть (обычно) один другой элемент данных для класса Shared_PTR - подсчет использования.
  2. Не могу ответить на это, я вообще использующные версии Boost, прежде чем был введен Make_shared (1.40?)
  3. Использовать Boost :: Const_PTR_CACT
  4. Shared_PTR имеет оператор == /! = Определено. В вашем примере выше: if (f)
3
ответ дан 30 November 2019 в 13:45
поделиться
  1. Одной из основных причин существования Shared_PTR является относительно дешевой для копирования.
  2. Существуют версии make_shared, которые принимают параметры (и если ваш компилятор поддерживает вариационные шаблоны, которые предпринимает список вариативных параметров).
  3. Это звучит так, как будто вы ищете const_ptr_cast?
  4. , чтобы вернуть нулевой указатель, вы можете пройти «0» на Chare_PTR CTOR. Чтобы проверить нулевой указатель, вы можете сравнить P.get () до 0.
2
ответ дан 30 November 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: