A Alpha II Medlem sedan maj 2000 2 993 inlägg Frågan 16 okt. 2003 13:00 #1 Jag behöver göra en class som hanterar texturer och kan användas överallt i programmet. Jag tror att lösningen på mitt problem är att använda en singleton. Jag har förstått att singleton classen har en statisk pekare till den faktiska klassen. Men hur ska resten av koden se ut? Hur kommer jag åt en medlemsvariabel, anropar medlemsfunktioner osv.
S SPiN Medlem sedan mars 2000 7 896 inlägg Du skapar en helt vanlig klass, med ett fält med en instans av sig själv. Klassen bör ha en privat konstruktor för att förhindra att instanser skapas. Du har sedan en statisk metod som returnerar samma objekt vid varje användning, och om instansen inte finns - skapas en ny.
Psuedo-kod:
klass Singleton [
privat Singleton av typen singl;
privat konstruktor [];
statisk publik Singleton getSingl() [
om singl är NULL skapa ny( Singleton->singl );
returnera singl;
];
];
Hajjar? :)
A Alpha II Medlem sedan maj 2000 2 993 inlägg mhm. men hur skapar jag en singleton om konstruktorn är privat?
S SPiN Medlem sedan mars 2000 7 896 inlägg Genom att anropa den statiska metoden som returnerar en Singleton:
Singleton MySingleton = Singleton.getSingl();
MySingleton.foo();
MySingleton.bar( foobar );
A Alpha II Medlem sedan maj 2000 2 993 inlägg Jag förstår ändå inte. :(
Jag vill använda min singleton i en funktion och srkiver så här:
CTimer timer = CTimer.Instance();
...men jag får ett felmeddelande om "illegal use of an expression" :(
Phorpher Medlem sedan feb. 2000 2 300 inlägg Har du lust att posta lite kod? :)
S SPiN Medlem sedan mars 2000 7 896 inlägg Hmm, hur ser din klass ut?
Så här hade jag gjort:
class CTimer {
private:
CTimer ctimer;
CTimer();
bool loaded;
public:
static CTimer getInstance();
bool getLoaded();
void setLoaded( bool );
};
CTimer CTimer::getInstance() {
if( !ctimer.getLoaded() )
ctimer.setLoaded( true );
return ctimer;
}
bool CTimer::getLoaded() {
return loaded;
}
void CTimer::setLoaded( bool bl ) {
loaded = bl;
}
Anropas:
CTimer ctimer = CTimer.getInstance();
Så gör jag i Java åtminstone, eftersom att mina C++-kunskaper är väldigt begränsade så vet jag inte om det är riktigt. :)
A Alpha II Medlem sedan maj 2000 2 993 inlägg timer.h
#ifndef _TIMER_H_
#define _TIMER_H_
class CFPSTimer;
class CTimer
{
public:
// Returns the real instance. If NULL create one.
static CTimer const * Instance();
// Returns the current time
__int64 GetTime() const;
// Returns the time elapsed since the given time (can be < 0)
__int64 ElapsedSince( __int64 start ) const;
// Returns true if the current time is later than the specified time
bool IsPast( __int64 end ) const;
// Converts ticks to seconds
static double ToSeconds( __int64 ticks );
// Returns the clock tick frequency (ticks per second)
__int64 GetFrequency() const { return m_Frequency; }
protected:
// Constructor
CTimer();
// Destructor
~CTimer();
private:
static __int64 m_Frequency;
static CTimer * m_pInstance;
};
//----------------------------------------------------------------------------------
inline __int64 CTimer::ElapsedSince( __int64 start ) const
{
return ( GetTime() - start );
}
inline bool CTimer::IsPast( __int64 end ) const
{
return ( ElapsedSince( end ) > 0 );
}
inline double CTimer::ToSeconds( __int64 ticks )
{
return double( ticks ) / double( m_Frequency );
}
#endif
timer.cpp
#define STRICT
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include "timer.h"
#include <windows.h>
CTimer * CTimer::m_pInstance = 0;
__int64 CTimer::m_Frequency = 1;
//----------------------------------------------------------------------------------
CTimer::CTimer()
{
LARGE_INTEGER frequency;
BOOL ok;
ok = QueryPerformanceFrequency( &frequency );
if ( ok == 0 )
{
// Error
}
m_Frequency = frequency.QuadPart;
}
//----------------------------------------------------------------------------------
CTimer::~CTimer()
{
}
//----------------------------------------------------------------------------------
CTimer const * CTimer::Instance()
{
if (m_pInstance == NULL)
m_pInstance = new CTimer;
return m_pInstance ;
};
//----------------------------------------------------------------------------------
__int64 CTimer::GetTime() const
{
LARGE_INTEGER time;
QueryPerformanceCounter( &time );
return time.QuadPart;
}
A Alpha II Medlem sedan maj 2000 2 993 inlägg Det var ett * tecken som saknades :r
CTimer [b]*[/b] timer = CTimer::Instance();