Умный указатель вопрос - PullRequest
       40

Умный указатель вопрос

4 голосов
/ 29 декабря 2010

Я переписываю свой код с помощью умного указателя.У меня такая ситуация:

void Foo(SomeClass *p) { }
boost::shared_ptr<SomeClass> p(new SomeClass);

Что теперь делать: передать исходный указатель из оболочки (p.get()) или переписать аргумент функции и передать смарт-указатель напрямую, например:

void Foo(boost::shared_ptr<Foo> obj) { }

IЯ не уверен.Как я понимаю, умные указатели должны следовать некоторому указателю и смотреть, нужно ли оно еще в программе.Таким образом, мы можем передать оригинальный указатель.

Ответы [ 4 ]

5 голосов
/ 29 декабря 2010

Если Foo не нужно (совместно) владеть *p, вы должны оставить подпись такой же и просто передать p.get().Это самый простой и гибкий вариант, требующий наименьшего изменения существующего кода.

3 голосов
/ 29 декабря 2010

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

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

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

2 голосов
/ 29 декабря 2010

Будет ли параметр Foo нулевым? Если ответ «нет», тогда вам действительно следует использовать ссылку вместо указателя:

void Foo(SomeClass &obj) { }

Использование:

boost::shared_ptr<SomeClass> obj(new SomeClass);
Foo(*obj);
0 голосов
/ 29 декабря 2010

Если ваша функция использует только указатель p для манипулирования или чтения объекта SomeClass, вы можете использовать p.get ().Если ваш указатель p назначен какой-либо другой переменной указателя или подобному, вы должны изменить сигнатуру функции.

...