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 );
    }
};

这是我的 Timer 单例代码。我想这样使用它:在玩家类的某个地方:

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

在主循环文件中:

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

但我得到这个错误:

1>Main.obj:错误LNK2019:未解析的外部符号“private:__thiscall CTimer::~CTimer(void)”(??1CTimer@@AAE@XZ) 在函数“void _ cdecl public: static class getInstance & __cdecl CTimer::getInstance(void)'::2'::`动态 atexit 析构函数中引用对于'实例''(void)" (?? _Finstance@?1??getInstance@CTimer@@SAAAV1@XZ@YAXXZ)

我认为这是因为主代码尝试在循环结束后调用析构函数,我应该更改为单例指针,但也许不是。你能告诉我如何解决这个问题吗?

4

5 回答 5

3

您的单例在退出时被破坏main(当然,如果它已被初始化)。所以它的析构函数被调用。你必须实现它(至少是空的)。否则你的程序无法链接

于 2013-05-21T11:37:47.460 回答
1

CTimer如果您的类的唯一成员是time_t变量,那么您不需要(未实现,因此链接错误)析构函数、复制构造函数和赋值运算符。只需注释这三行:这些函数将由编译器生成!

于 2013-05-21T11:38:20.200 回答
1

您必须为析构函数提供一个实现,因为它在 main 返回时被调用:

~CTimer() {}
于 2013-05-21T11:39:36.330 回答
1

您在没有为析构函数编写主体的情况下阻止对象的破坏,因此会导致链接错误。请写析构函数的主体

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

示例代码:http: //ideone.com/TqtLVX#view_edit_box

于 2013-05-21T11:54:26.463 回答
0

第一:您是否希望破坏唯一实例?如果你希望它被破坏,你必须在某个地方为你的析构函数提供一个主体(即使它是空的),或者你不能自己声明它(这会使它公开,但这不应该是一个问题)。在 C++11 中,您还可以声明它= default,它告诉编译器生成它通常会为实现生成的内容。

然而,大多数时候,您不希望单例被破坏。使用单例的主要原因之一是为了解决初始化顺序问题;破坏它会为破坏顺序问题敞开大门。通常的习惯用法是使用指向单例的静态指针,在实例函数中测试它是否为空,如果是则分配一个新实例。(如果我可以相信该评论,这表明该类仅在渲染期间使用,那可能并不重要,因为一旦您调用exit或返回 单例,您将不会对单例做任何事情main。)

于 2013-05-21T12:51:03.667 回答