void f(boost::shared_ptr<X> const& p);
От: Alexander G Украина  
Дата: 29.12.09 09:29
Оценка:

Правило 20: Предпочитайте передачу по ссылке на const передачу по значению

(Скотт Мейерс, Эффективное использование C++
Автор(ы): Скотт Мейерс

Эта книга представляет собой перевод третьего издания американского бестселлера Effective C++ и является руководством по грамотному использованию языка C++. Она поможет сделать ваши программы более понятными, простыми в сопровождении и эффективными. Помимо материала, описывающего общую стратегию проектирования, книга включает в себя главы по программированию с применением шаблонов и по управлению ресурсами, а также множество советов, которые позволят усовершенствовать ваши программы и сделать работу более интересной и творческой. Книга также включает новый материал по принципам обработки исключений, паттернам проектирования и библиотечным средствам.
)

Стоит ли передавать boost::shared_ptr<X> по константной ссылке?

С одной стороны, подсчёт ссылок может дорого стоить.

но недостатков много:

  • Добавляется косвенность (если ссылки реализованы как указатели).
  • Больше букв писать.
  • const ссылка может создавать иллюзию константности.
  • Оно хорошо только если типы совпадают, иначе — преобразование всё равно нужно.
    class Y : X {};
    void f(boost::shared_ptr<X const> const& p);
    
    boost::shared_ptr<Y const> p1;
    boost::shared_ptr<X> p2;
    f(p1); // временый boost::shared_ptr<X const> создаётся
    f(p2); // временый boost::shared_ptr<X const> создаётся


    Как вообще бороться с оверхедом на подсчёт ссылок и стоит ли?

    Кстати, в Delphi для типов, для которых подсчёт ссылок встроен в компилятор, всё просто и без увеличения уровня косвенности:


    procedure P1(S: string; I: IUnknown);
    begin (* неявное увеличение числа сссылок на S и AddRef для I *)
        
      S := F1(); I := F2(); (* можно *)
    
    end; (* неявное уменьшение числа сссылок на S и Release для I *)
    
    
    procedure P2(const S: string; const I: IUnknown); (* передаются значения указателей, а не указатели на указатели *)
    
    begin (* неявных операций с I и S нет *)
        
      S := F1(); I := F2(); (* нельзя - ошибка компиляции *)
    
    end; (* неявных операций с I и S нет *)
  • Русский военный корабль идёт ко дну!
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.