Правильно ли вы создаете класс sinlgeton by weak_ptr
Я создаю родительский класс для обработки шаблона singleton со смарт-указателем:
.h файл:
template<class singleType>
class Singleton
{
public:
static std::shared_ptr<singleType> GetInstance();
private:
static std::weak_ptr<singleType> m_singleObject;
};
.cpp файл:
template<class singleType>
std::shared_ptr<singleType> Singleton<singleType>::GetInstance()
{
auto shareObject = m_singleObject.Lock();
if (!shareObject)
{
shareObject.reset(new singleType);
m_singleObject = shareObject;
}
return shareObject;
}
Не уверен, что это правильный способ использования умного указателя?
Любая идея?
Большое спасибо
Ответы
Ответ 1
Проценты и минусы этой реализации уже обсуждаются. Но есть куча ошибок:
1) Поскольку это шаблон, вы должны перенести свою реализацию в заголовок, или компоновщик не может его найти.
2) Функция .lock()
слабой_ptr не находится в капиталах.
3) Не забудьте создать экземпляр
template<class singleType>
std::weak_ptr<singleType> Singleton<singleType>::m_singleObject;
4) Лучше использовать shareObject = std::make_shared<singleType>(singleType());
вместо new
: http://herbsutter.com/gotw/_103/
5) Как сказал Конрад: он не защищен потоками.
Ответ 2
Я провел некоторое исследование, поэтому теперь отправлю ответ.
Код выглядит так, как будто он должен работать, и это правильное использование интеллектуальных указателей. Вопрос только в том, как именно вы хотите, чтобы синглтон себя вел. Это должно вести себя как учебник singleton EXCEPT для поведения, который, если в настоящее время нет указателя на синглтон, он удалит себя. Такое поведение действительно зависит от реализации вашей программы. Если вы хотите, чтобы singelton существовал только тогда, когда он используется, я бы сказал, что нужно пойти на это.
Я бы просто избегал создавать и разрушать singelton слишком часто, особенно если строительство и деконструкция особенно интенсивны. Если он постоянно создается и удаляется, вам, вероятно, лучше работать с более стандартной версией singleton. Стандартное поведение singleton имеет тенденцию к тому, что singleton создается только один раз во время работы программы и никогда не удаляется.
Я думаю, что это умная реализация, учитывая, что вы используете ее, и мне, возможно, придется занять эту идею.
Ответ 3
Ваш код не является потокобезопасным.
Имя lock
может предполагать, что одновременный доступ блокируется, но на самом деле нет такой гарантии: когда несколько потоков одновременно вызывают функцию GetInstance
, вы получите несколько экземпляров вместо того, чтобы гарантировать один.
Вам нужно создать явную блокировку для всей продолжительности жизни функции GetInstance
. Обратите внимание, что это, конечно, не очень эффективно.
Ответ 4
Насколько мне известно, все должно быть хорошо. Вы избегаете проблем с уничтожением порядка, но может возникнуть проблема с созданием новых экземпляров после создания вашего первого экземпляра. Этот синглтон будет иметь только один экземпляр в любой момент, но в течение программы, запускающей более одного экземпляра, возможно, был жив в целом.
Это разрушение и отдых также могут быть нежелательными с точки зрения производительности, а не только в побочных эффектах.