Я согласен. Я прочитал RSS-тэг C-тэга и вижу множество вопросов по C ++, которые на самом деле не имеют никакого отношения к C.
Я также часто вижу этот обмен:
Аскер: Как вы делаете это в C?
Ответ: Используйте библиотеку X для C ++.
Аскер: Хорошо, а как насчет того, чтобы кто-то действительно ответил на мой вопрос в Си?
Безопасность потоков - несколько экземпляров могут быть созданы, если GetInstance () вызывается из конкурирующих потоков.
См.: Очевидная реализация синглтона для .NET?
При реализации шаблона синглтона следует учитывать несколько факторов.
Ниже приведен хороший шаблон общего назначения, который вы могли бы следовать. Его потокобезопасный, запечатанный, использует свойства, а defer создает экземпляр singleton.
public sealed class Singleton
{
static class SingletonCreator
{
// This may seem odd: read about this at: http://www.yoda.arachsys.com/csharp/beforefieldinit.html
static SingletonCreator() {}
internal static readonly Singleton Instance = new Singleton();
}
public static Singleton Instance
{
get { return SingletonCreator.Instance; }
}
}
Другие упоминали безопасность потоков. Также есть тот факт, что они забыли пометить его как запечатанный
, чтобы вы могли наследовать от него и таким образом создать несколько экземпляров.
У вас есть потенциальное состояние гонки в многопоточном коде. Каждый из двух потоков может пройти нулевую проверку до того, как конструктор в другом потоке будет завершен, так что оба могут закончить построение класса.
Код не является потокобезопасным. Для этого вам необходимо сделать следующее:
public class Class1
{
private static Class1 oInstance = null;
private Class1() { }
public static Class1 GetInstance()
{
if (oInstance == null)
{
lock(typeof(Class1))
{
if (oInstance == null)
{
oInstance = new Class1();
}
}
}
return oInstance ;
}
}
Это наиболее эффективный способ ленивой загрузки экземпляра, поскольку он только мешает заблокировать (может быть дорогостоящим), когда есть подозрение, что экземпляр не будет создан для следующего вызова . Повторная проверка блокировки гарантирует, что она будет создана только один раз.
Существует потенциальная проблема с этим, если у вас многопоточное приложение. Это может привести к созданию более одного экземпляра, если два потока запрашивают одновременно.
Я бы взглянул на эту страницу на Синглтонах в C # . В нем подробно показана проблема, а также представлены лучшие варианты.
Итак, решение следующее?
public class Class1
{
private static Class1 oInstance = new Class1();
private Class1() { }
public static Class1 GetInstance()
{
return oInstance ;
}
}
Отсутствует потокобезопасность, эта страница прекрасно это объясняет.
Не работают в этой компании. Шаблон singleton не часто используется, и его применимость в чистой объектно-ориентированной системе сомнительна. Отмена одноэлементного шаблона - огромная проблема, если вам когда-нибудь понадобится превратить его обратно в нормально построенный объект.