webForumDet fria alternativet

Singleton

8 svar · 522 visningar · startad av Alpha II

Alpha IIMedlem sedan maj 20002 579 inlägg
#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.

SPiNMedlem sedan mars 20005 832 inlägg
#2

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? :)

Alpha IIMedlem sedan maj 20002 579 inlägg
#3

mhm. men hur skapar jag en singleton om konstruktorn är privat?

SPiNMedlem sedan mars 20005 832 inlägg
#4

Genom att anropa den statiska metoden som returnerar en Singleton:

Singleton MySingleton = Singleton.getSingl();
MySingleton.foo();
MySingleton.bar( foobar );
Alpha IIMedlem sedan maj 20002 579 inlägg
#5

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" :(

PhorpherMedlem sedan feb. 20002 059 inlägg
#6

Har du lust att posta lite kod? :)

SPiNMedlem sedan mars 20005 832 inlägg
#7

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. :)

Alpha IIMedlem sedan maj 20002 579 inlägg
#8

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;
}
Alpha IIMedlem sedan maj 20002 579 inlägg
#9

Det var ett * tecken som saknades :r

CTimer [b]*[/b] timer = CTimer::Instance();
Genererad på 387 ms · cache AV · v20260730165559-full.f96bc7eb