Singeltons
Förord
Denna artikel beskriver vad singeltons är samt hur det används genom kodexempel.Innehåll
Singeltons är ganska lätta att implementera och det ska vi visa.
Vi kommer skriva en simpel och begränsad fel-loggar klass. Varför jag just väljer att skriva en logger-klass är därför att man ofta endast vill ha en instans som kan skriva till en fil. Detta är bra då man inte ska kunna öppna för många strömmar till en fil och glömma avsluta dem.
error_logger.h
error_logger.cpp
main.cpp
Vi kommer skriva en simpel och begränsad fel-loggar klass. Varför jag just väljer att skriva en logger-klass är därför att man ofta endast vill ha en instans som kan skriva till en fil. Detta är bra då man inte ska kunna öppna för många strömmar till en fil och glömma avsluta dem.
error_logger.h
#pragma once
#include
#include
using namespace std;
Class CErrorLogger
{
public:
// Vi använder denna klass för att skapa den enda instansen av våran klass.
static void create();
//Denna kommer öppna våran fel-fil.
void openLog(const char *fileName);
//Denna kommer stänga filen.
void closeLog();
// Denna kommer skriva ut texten som funktionen tar in, ut till filen man specifierar i
// ”openLog()”.
void Output(const char *errorText);
static CErrorLogger* getInstance()
{ return m_instance; }
//destroy() förstör instansen av klassen.
Static void destroy();
private:
//Våran ut-ström till filen.
ofstream m_fileOut;
// Våran enda instans som kommer vara tillåten i vårat program.
static CErrorLogger m_instance;
// Nu gör vi något som inte är allt för vanligt.
// Vi gör konstruktorn, copy konstruktorn och tilldelnings operatorn samt destruktorn
// till privata medlems funktioner. Detta kommer du se i alla singeltons. Detta är en stor
// del av vad som gör en singelton till just en singelton.
// Genom att göra dom privata hindrar vi att dessa funktioner körs i någon anna fil, så om
// vi skulle göra:
// int main()
// {
// CErrorLogger errorLogger;
// return 0;
// }
// Skulle kompilatorn ge ett felmedelande något med ”Du försöker köra en privat
// metod”.
// Därför gör vi konstruktorn, destruktorn osv. Privata för att vara säkra på att ingen
// annan instans av klassen skapas.
CErrorLogger() {}
CErrorLogger(const CErrorLogger&) {}
CErrorLogger& operator = (const CErrorLogger&) { reutrn *this; }
~CErrorLogger() {}
};
error_logger.cpp
#include ”error_logger.h”
CErrorLogger* CErrorLogger::m_instance = NULL;
void CErrorLogger::create()
{
// Utifall det inte finns någon instans, skapa en.
if(m_instance == NULL)
{ m_instance = new CErrorLogger; }
}
void CErrorLogger::openLog(const char *fileName)
{
if(!fileName)
{ retrun; }
// Vi vill inte försöka öppna en fil som redan är öppen, därför stänger vi den.
closeLog();
m_fileOut.open(fileName, ios_base::out | ios_base::app);
// Kollar efter fel.
if(!m_fileOut)
{ cout << ”Kunde inte öppna filen” << endl; }
}
void CErrorLogger::closeLog()
{
if(m_fileOut.is_open())
{ m_fileOut.close(); }
}
void CErrorLogger::Output(const char *errorText)
{
// Kolla om fel
if(!errorText)
{ return; }
// Skriv ut till filen.
m_fileOut << errorText << endl;
}
void CErrorLogger::destroy()
{
If(m_instance)
{
delete m_instance;
m_instance = NULL;
}
}
main.cpp
#include “error_logger.h”
int main()
{
CErrorLogger::create();
CErrorLogger::getInstance()->openLog(“fel.txt”);
CErrorLogger::getInstance()->Output(“Ett fel”);
CErrorLogger::getInstance()->closeLog();
CErrorLogger::destroy();
return 0;
}
Niklas Jansson
Koden är lite tråkig, och har en äldre, namnkonvention. Till exempel skulle en std::string passa bättre än char*. Dessutom kan man (åtminstone i princip) använda referenser istället för pekare.
Johan Segolsson
Ta inte för illa upp nu men jag tycker inte det här är värdigt att kallas artikel, det här är ett kodexempel... I en artikel tycker jag du inte ska infoga all kod du har i. Du borde istället satsa på att förklara vad som utmärker singeltons, användningsområden osv. Du kan/ska självklart ha med kodexempel men du ska inte infoga hela koden i exemplen utan endast dom små delarna som behöver förklaras, resten av koden borde ligga i en zip fil eller liknande som läsaren kan ladda ner om han/hon känner för det.