2014-09-19 7 views
4

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

То есть, я изначально имел мои одиночка как указатели, как это:

static MapReader* Instance() 
{ 
    if (instance == 0) 
    { 
     instance = new MapReader(); 
     return instance; 
    } 
    return instance; 
} 

Однако я всегда чувствовал, что использование слишком много указателей плохо для утечек, и я предпочитаю не использовать их, если я могу помочь ему (или умные указатели, если мне нужно). Так что я изменил все мои одиночка на ссылки, как это:

static MapReader& Instance() 
{ 
    static MapReader instance; 
    return instance; 
} 

Однако, теперь я замечаю свою игру отставать в нечетные разы, а затем ускорить, как и FPS немного шаткий.

Мой вопрос в том, что; ли ссылочный синглтон все накапливается в стеке? или они все еще распределяются по куче? И должен ли я изменить их обратно на указатели с помощью интеллектуальных указателей?

ответ

3

Это почти наверняка не на куче в силу того факта, что он не создан с помощью new.

Однако стандарт отключен от , где размещены переменныеstatic, в которых указаны только их поведение . Смотрите, например, C++11 3.7.1:

1/Все переменные, которые не имеют динамический срок хранения, не имеют срок хранения нити, а не локальные имеют статическую продолжительность хранения. Хранение данных объектов должно продолжаться на протяжении всей программы (3.6.2, 3.6.3).

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

3/Ключевое слово static может использоваться для объявления локальной переменной со статической продолжительностью хранения.

4/Ключевое слово static, примененное к элементу данных класса в определении класса, дает время статического хранения элемента данных.

Это в значительной степени степень того, что сам стандарт налагает на них.

Большинство реализаций, скорее всего, будут областью отдельно от кучи и стека для хранения переменных статической продолжительности хранения.

Это также почти наверняка не использование статики и ссылок, которые замедляют ваш код. Глубоко взглянув на компиляторы и то, как они работают, статистика обычно находится в наименее так же быстро, как и другие переменные, так как они очень быстр найти в памяти.

Как вариант, у вашего указателя варианта синглтона есть две проблемы.Во-первых, это потенциальное состояние гонки, если вы работаете в многопоточной среде. Существует вероятность того, что может быть создано несколько объектов, если отдельные потоки вызывают Instance().

В частности, если поток А входит в оператор if, то поток B запускается, B может пройти, создать объект, а затем вернуться. Если затем A, он создаст объект .

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

Вторая проблема - только конфеты. Там нет необходимости возвращать объект внутри if блока, так как он будет возвращен, когда вы дойдете до нижней функции:

static MapReader* Instance() { 
    if (instance == 0) 
     instance = new MapReader(); 
    return instance; 
} 
+0

Я беспокоюсь, что это может замедлить мой код из-за слишком большого количества стека. поэтому я обеспокоен тем, где размещаются синглтоны. – Oria

+0

Слишком много стека не замедлит ваш код. Это может привести к его краху, если вы продуваете размер, но ссылка не более опасна, чем указатель. – paxdiablo

+0

Хорошо, что хорошо знать, что это не замедлит работу и просто потерпит крах. Пока у меня не было крушения, просто странный прыжок FPS. – Oria

1

Ни то, ни другое. Статические переменные внутри функций находятся в разделе данных. Для записи так же статические переменные вне функций и глобальные.

+0

Я призываю вас, чтобы найти _one_ упоминание о разделе данных в стандарте ISO: -) – paxdiablo

+0

И как это важно? –

+0

Это актуально, потому что C++ не имеет понятия раздела данных. _implementation_ может сделать это определенным образом, но это не предусмотрено. Технически переменные статического хранения _could_ должны находиться в куче, поскольку соответствующая реализация может 'new' их всех до вызова' main() '. – paxdiablo

Смежные вопросы