2010-02-24 3 views
6

В настоящее время я пытаюсь исправить несколько недостатков в нашей базе кода, введя использование интеллектуальных указателей. Кодовая база очень большая и взаимосвязана, как паук, у которого было много кофе.Как внедрить boost :: shared_ptr в существующую (большую) C++-кодовую базу?

Мне было интересно, пытались ли люди раньше и каков был их подход.

Мой первый шаг был сделан для классов typedef, как показано ниже.

#ifndef USE_SMART_POINTERS 
    #define USE_SMART_POINTERS 0 
#endif 

#if USE_SMART_POINTERS == 1 
    #include <boost/smart_ptr.hpp> 
#endif 


namespace ProductX 
{ 
    // forward decleration 
    class CTObject; 


    //typedefs 
    #if USE_SMART_POINTERS == 1 
     typedef boost::shared_ptr<CTObject> CTObjectPtr; 
    #else 
     typedef CTObject* CObjectPtr; 
    #endif 
} 

Теперь я понимаю, что это приведет к богатству компиляции областей, такие вещи, как

CTObjectPtr i = NULL; 

Будет укомплектовать Bork когда умные указатели включены.

Мне было интересно, есть ли что-нибудь, что я мог бы сделать на этом раннем этапе, чтобы уменьшить массу ошибок компиляции, или это, как я подозреваю, просто беру вещи в каждом конкретном случае.

Приветствие Rich

ответ

9

Не делайте этого: я имею в виду определения типов.

Предположительно старый код имеет как минимум delete звонки в нем? Который, конечно, потерпит неудачу в случае умного указателя.

Умный указатель на некоторые вещи или нет, то есть преследует конкретный экземпляр через базу кода. Заставьте это работать, затем переходите. Удачи!

+0

Глядя на богатство кода, я начинаю думать, что вы правы. Спасибо, что остановили меня на безумном отборе кода. – Rich

6

Вместо того чтобы пытаться внедрить интеллектуальные указатели везде, вы можете использовать сборщик мусора Boehm-Demers-Weiser и оставить свою базу кода неповрежденной.

Он также позаботится о циклических ссылках.

+3

+1: важно отметить циклические ссылки. Это то, о чем нужно позаботиться, если использовать интеллектуальные указатели (используя 'weak_ptr' для прерывания циклов) –

+6

Важным моментом в сборщике Boehm является то, что он консервативен - не гарантируется очистка всего мусора. Он также не является детерминированным, как и все не связанные с подсчетом коллекционеры. – Joel

3

Нет простого способа сделать это. Как вы узнали, boost::shared_ptr s и стандартные указатели не являются взаимозаменяемыми. Что вы здесь делаете, это рефакторинг кода, и, к сожалению, рефакторинг занимает много времени и может быть очень утомительным.

Как указано в sdg, typedef Указатели для shared_ptr s - не очень хорошая идея, и просто увеличивает количество кода, который вы должны написать.

Во-первых, я бы определил указатели, которые на самом деле необходимо изменить на shared_ptr. Очевидно, вы не хотите менять все указатели на shared_ptr. Большинство из них, вероятно, были бы лучше, чем std::auto_ptr s или boost::scoped_ptr s, а некоторые были бы лучше, как boost::weak_ptr, и, наконец, некоторые из них могли бы быть прекрасными, как простые указатели стиля C.

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

+0

Возможно, самый простой способ начать такое преобразование (если вы уверены, что конкретный тип всегда должен быть либо 'shared_ptr', либо' weak_ptr'), должен использовать шаблон самозаверяющего компьютера - создать статический shared_ptr X: : create (...) и изменить конструктор на закрытый или защищенный. Теперь исправим все ошибки компилятора. Используйте только один тип за раз! (Ну, вам, возможно, придется делать производные классы одновременно). – Miral

0

Я бы очень ограничил введение shared_ptr в существующую большую базу кода. Если вы действительно хотите использовать интеллектуальные указатели для исправления ошибок, я предлагаю использовать указатели с областью действия и, кроме того, я бы использовал код рефакторинга и создал четкое право собственности.

Смежные вопросы