2009-09-22 2 views
1

К моему большому стыду, у меня не было возможности использовать интеллектуальные указатели в реальной разработке (супервайзер считает это слишком «сложным» и пустой тратой времени). Тем не менее, я планировал использовать их для своих собственных ...C++ и Smart Pointers - как бы умные указатели помогли в этой ситуации?

У меня есть ситуации, связанные с деинсталляцией модуля после их завершения или при загрузке новых данных. Поскольку я использую указатели, я нахожу свой код завалено проверкой на нуль, такие, как эти ...

// TODO: Reset all opened windows 

// Deinit track result player 
if (trackResultPlayer_) 
    trackResultPlayer_->reset(); 

// disconnect track result player 
disconnect(trackResultPlayer_); 

disconnect(trackResultAnimator_); 
} 

if (videoPlayerWindow_) 
{ 
    videoPlayerWindow_->reset(); 

    // Disconnect the video player window from source movie data 
    disconnect(videoPlayerWindow_); 
} 

// Disconnect this module from its children as they would be connected again 
disconnect(this); 

Если я использовать смарт-указатели, вместо сырых указателей, как бы эта проблема быть смягчена?

+0

Помните, что новый не возвращает NULL (если вы явно не задаете вопрос). –

ответ

4

Сделайте каждый из ваших классов реализацией деструктора, который выполняет всю очистку/деинициализацию, необходимую для этого класса.

Создайте экземпляр класса и заверните его в boost::shared_ptr.

Затем передайте копии каждой функции, которая нуждается в доступе к экземпляру.

И умный указатель гарантирует, что как только объект больше не будет использоваться (когда все общие указатели были уничтожены), объект, на который они указывают, будет уничтожен. его деструктор запускается, и вся очистка выполняется.

Как всегда на C++, используйте RAII, когда это возможно.

Всякий раз, когда у вас есть код, как x.reset() или disconnect(x), первое, что вам нужно сделать, это спросить себя: «Разве это не принадлежит деструктору?»

Кроме того, всякий раз, когда вы используете x->y() вы должны спросить себя:

  • Почему это указатель? Не могу ли я сделать с одним экземпляром, выделенным в стеке, и, возможно, несколькими ссылками на него?
  • Если это должен быть указатель, почему он не является умным указателем?
2

Умный указатель - это прежде всего инструмент для управления направленной памятью. Они не предназначены для чего-то, что освободит вас от бремени проверки значения NULL ...

В вашем примере кода я не вижу большого потенциала для умных указателей, уменьшающих сложность кода, если вы не перемещаете вызовы как videoPlayerWindow_->reset(), disconnect(videoPlayerWindow_) и т. Д. В деструктор класса, videoPlayerWindow является экземпляром.

+0

-1. Умные указатели используются (и рекомендуется) для управления * любым * типом ресурса, который может использоваться несколькими владельцами, а не только памятью. «Они не предназначены для чего-то, что освободит вас от бремени проверки значения NULL»: в общем, это правда, но в этом конкретном случае проверка NULL заключается в том, чтобы проверить, нужна ли очистка, какие интеллектуальные указатели с соответствующими деструкторами * будут * заботиться. «Я не вижу большого потенциала для умных указателей, уменьшающих сложность кода, если только ...» LOL! Сравните: «Я не вижу большого смысла в еде, если вы ее не едите». –

+1

Думаю, я упомянул деструкторов. Я не могу сделать вывод (из кода, предоставленного OP), действительно ли использование деструкторов для очистки является реально возможным способом. – Dirk

+0

Полагаю, мы не согласны с этим - для меня код OP кричит, чтобы содержимое этих блоков if if было помещено в деструкторы (в частности, деструктор для класса, указатель которого проверяется на NULL). –

2

Проверки против NULL не являются проблемой - и интеллектуальные указатели не вмешиваются в это.