Re[3]: Возврат умного указателя из dll
От: Кодт Россия  
Дата: 06.12.05 18:46
Оценка:
Здравствуйте, Аноним, Вы писали:

К>>А ещё можно было вынести "службу подсчёта ссылок" в отдельную dll, в виде функций

К>>и пусть твои шаблоны пользуются этими функциями на здоровье.
А>В данном случае это не прокатит. Поскольку эту dll должен кто-то загрузить. А XML-парсер нужен моему CcApllication для чтения настроек при старте. Хм... правда можно эту либу статически прилинковать к exe. Ну да ладно, будет тормозить через фабрику тогда поковыряем.

Именно так: статически линковать — и к экзе, и к длл, в которой эти шаблоны встречаются.
А чтобы с настройками проекта не возиться, прямо в хедере пишешь #pragma comment(lib)
#ifndef __REFCOUNT_H__
#define __REFCOUNT_H__
//////////////////////////////////////////////////////////
// refcount.h, implemented in refcount.cpp -> refcount.dll

#ifdef REFCOUNT_IMPL
  #define REFCOUNT_API __declspec(dllexport)
#else
  #define REFCOUNT_API __declspec(dllimport)
  #pragma comment(lib, "refcount.lib") // эквивалентно опции линкера /LIB refcount.lib
#endif

namespace refcount {
REFCOUNT_API int addref(void* p);
REFCOUNT_API int decref(void* p);
}

#endif//__REFCOUNT_H__


К>>Вообще, зачем делать такой странный подсчёт ссылок? Чем не понравился, к примеру, boost::shared_ptr?

А>Boost еще к Builder C++ 6 прикрутить надо.

Тююю. А что, не прикручивается? shared_ptr.hpp — это же такой простой зверь.

А>Пробывал stl::auto_ptr не прокатил, он убивал объект когда не него еще были другие ссылки. Ведь про другие stl::auto_ptr на тот же объект он ничего не знает и сносит объект, когда помирает сам.


К>>Или очень нужна была интрузивность?

А>Что за зверь "интрузивность" ?

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

Свойство "подсчёт ссылок".
Интрузивные реализации
— счётчик содержится прямо внутри объекта (пример: COM)
— глобальная таблица (та самая refcount.dll)
— идентичность объекта обеспечивается не указателем, а хэндлом; механика подсчёта спрятана за API (пример: объекты ядра и GDI в виндоузе)
Неинтрузивные реализации
— семейство указателей (на один и тот же объект) размещает на куче счётчик, которым также совместно владеет (boost::shared_ptr)
— семейство указателей ссылается друг на друга (linked_ptr Максима Егорушкина)

Свойство "удаление объекта"
Интрузивные реализации
— delete ptr вызывающее виртуальный деструктор
— ptr->Release() — внутри проверяется счётчик ссылок и если он йок, то объект делает delete this
Неинтрузивные реализации
— shared_ptr при конструировании запоминает указатель на функцию checked_delete<Y> того типа, который ему отдан; когда счётчик обнулится, он вызовет именно эту функцию. Не имеет значения, произошло ли это в том же модуле, где объект создан, или в другом (с другим менеджером памяти) — вызовется правильный.
— тому же shared_ptr'у можно подсунуть любую функцию, а не только checked_delete — если объект дОлжно утилизировать иным способом (например, CloseHandle())

К>>Кстати говоря, нужно быть очень аккуратным, когда делаешь внешний счётчик ссылок. Кастинг туда-сюда, и получаешь другое значение указателя на тот же самый объект.

А>Через фабрику проблем нет, всегда получаем что надо. Ибо ручками никаких кастов не делаем.

Ну если гарантируется, что наследование только одиночное — то без проблем.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.