Здравствуйте, WolfHound, Вы писали:
WH>Псевдокод можно? А то словами у тебя както не очень получилось объяснить.
Можно.
БЫЛО
// типы
template <typename T>
class singleton
{
public:
static T & get_instance()
{
static T instance;
return instance;
}
};
class logger
{
friend singleton<logger>;
private:
logger();
public:
void log(const char * message) const;
}
// использование
singleton<logger>.get_instance().log("some text");
СТАЛО
// типы
template <typename T>
class singleton
{
public:
static T & get_instance()
{
static T instance;
return instance;
}
};
class logging_part
{
public:
virtual void log(char * message, bool * is_canceled, bool * is_handled) = 0;
}
class text_logging_part : public logging_part
{
public:
virtual void log(char * message, bool * is_canceled, bool * is_handled);
}
class db_logging_part : public logging_part
{
public:
virtual void log(char * message, bool * is_canceled, bool * is_handled);
}
class logger
{
public:
void log(const char * message) const;
void add_part(logging_part * log, /* какие-то параметры указывающие приоритет вызова и т.п. */);
void remove_part(logging_part * log);
}
// использование
text_logging_part tl;
db_logging_part dl;
singleton<logger>.get_instance().add_part(tl);
singleton<logger>.get_instance().add_part(dl);
// Вот тут ничего не поменялось. Если нужна ещё и бинарная совместимость, то делаем интерфейсы.
singleton<logger>.get_instance().log("some text");
A>>И сделать синглтон проще, чем трахаться с временем жизни unmanaged обёрток. А я, надо заметить, имею большой сексуальный опыт в этой сфере
WH>Ни разу со временем жизни проблем не возникало.
Проблема очевидная. Пишешь managed обёртку в виде какого-нибудь
class ManagedWrapper
{
public event RakeEventHandler Rake
{
add
{
NativeMethods.AddCallbackTarget(value, GetContextForObject(value).ToIntPtr());
}
remove
{
NativeMethods.RemoveCallbackTarget(value, GetContextForObject(value).ToIntPtr());
}
}
}
и потом в коде
ManagedWrapper mw;
mw.Rake += MyHandler;
И получаешь грабли, потому что делегат указывавший на метод MyHandler был собран сборщиком мусора как неимеющий managed ссылок. Прямо скажем — неприятно. Приходится переписывать в виде
class ManagedWrapper
{
public event RakeEventHandler Rake
{
add
{
SomeGlobalDelegateTable.Add(value);
NativeMethods.AddCallbackTarget(value, GetContextForObject(value).ToIntPtr());
}
remove
{
NativeMethods.RemoveCallbackTarget(value, GetContextForObject(value).ToIntPtr());
SomeGlobalDelegateTable.Remove(value);
}
}
}
потому что заставлять клиента явно создавать делегат и хранить на него ссылку не катит.
Таких сюрпризов у меня в своё время было не мало.
WH>Я вот не помню ни одного случая когда отложенная инициализация имела смысл.
Случай простой — инициализация тяжёлая операция и не всегда нужная. Мне, например, не нравятся приложения стартующие 2-3 минуты потому что программист не стал заморачиваться и решил инициализировать всё сразу.