2013-05-21 2 views
0
#pragma once 
#include <time.h>   

class CTimer 
{ 
    time_t _last; 
    CTimer() { _last = time(NULL); } 
    CTimer(const CTimer &); 
    CTimer& operator=(const CTimer&); 
    ~CTimer(); 
public: 
    static CTimer& getInstance(){   
     static CTimer instance; 
     return instance; 
    } 

    float getDelta(){ 
     time_t now = time(NULL); 
     float delta = (float)(now - _last);  
     return delta; 
    } 
    //should be called at the beginning of rendering function 
    void update(){ 
     _last = time(NULL); 
    } 
}; 

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

posX += vel * CTimer::getInstance().getDelta(); 

И в главном файле петли:

void gameLoop(){ 
CTimer::getInstance().update(); 
... 
} 

Но я получаю эту ошибку:

1>Main.obj : error LNK2019: unresolved external symbol "private: __thiscall CTimer::~CTimer(void)" ([email protected]@[email protected]) referenced in function "void _cdecl public: static class getInstance & __cdecl CTimer::getInstance(void)':: 2'::`dynamic atexit destructor for 'instance''(void)" (??[email protected][email protected]@@[email protected]@YAXXZ)

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

+0

Предоставляли ли вы тело для деструктора? – JBL

ответ

1

Если единственным членом вашего класса CTimer является переменная time_t, вам не нужен деструктор (не реализованный, следовательно, связующая ошибка), конструктор копирования и оператор присваивания. Просто прокомментируйте эти три строки: эти функции будут сгенерированы компилятором!

+0

Если OP требует, чтобы деструктор был закрыт, комментирование этого не будет делать. – juanchopanza

+1

Кроме того, синглтон не должен иметь конструктор копирования или оператор присваивания. – juanchopanza

+0

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

3

Ваш синглтон разрушен, когда вызывается main (если он был инициализирован, конечно). Так называется деструктор. Вы должны его реализовать (по крайней мере, пустым). В противном случае ваша программа не может быть связана

1

Вы должны обеспечить реализацию для деструктора, так как он вызывается, когда главные возвращения:

~CTimer() {} 
1

Вы блокирующее разрушение объекта без написания тела деструктора, так что приводят к ошибке ссылки. Пожалуйста, напишите тело деструктора

~CTimer() 
    {} //code to free any resource 

Пример кода: http://ideone.com/TqtLVX#view_edit_box

0

Первое: вы хотите уникальный экземпляр, чтобы быть уничтожены или нет? Если вы хотите, чтобы это было разрушено, вы должны либо предоставить тело для вашего деструктора где-нибудь (даже если оно пустое), либо вы должны не объявлять его сами (что сделало бы его общедоступным, но что не должно быть проблема). В C++ 11 вы также можете объявить его = default, в котором компилятор должен сгенерировать то, что будет генерировать для реализации.

Большую часть времени, однако, вы не хотите, чтобы одиночный сингл был разрушен. Одной из основных причин использования синглета является порядок решения проблем инициализации; разрушающий его оставляет дверь открыта для заказа проблем с разрушением. Обычным idiom было бы использование статического указателя на singleton, тестирование , независимо от того, является ли оно нулевым в функции экземпляра и выделяет новый экземпляр, если он есть. (Если я могу поверить в комментарий, который предполагает, что этот класс используется только во время рендеринга, он, вероятно, не имеет значения, так как вы ничего не будете делать с синглтон, как только вы позвонили exit или вернулись из main.)

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