add example from Curtis Krauskopf's CUJ article 'Creating Dynamic Singletons & the Loki Library' - www.decompile.com
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@306 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
6548c6e1d7
commit
6c7cedb361
4 changed files with 239 additions and 1 deletions
32
test/Longevity/Makefile2
Executable file
32
test/Longevity/Makefile2
Executable file
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
|
||||||
|
CPP = g++
|
||||||
|
CC = gcc
|
||||||
|
OBJ = main2.o
|
||||||
|
LINKOBJ = main2.o
|
||||||
|
CXXINCS = -I./../../include
|
||||||
|
LIBS = -L../../lib -lloki
|
||||||
|
CXXFLAGS = $(CXXINCS) -O2 -DNDEBUG
|
||||||
|
BIN = main2-gcc.exe
|
||||||
|
RM = rm -f
|
||||||
|
CHK_DIR_EXISTS= if not exist
|
||||||
|
MKDIR = mkdir
|
||||||
|
|
||||||
|
.PHONY: all all-before all-after clean clean-custom
|
||||||
|
|
||||||
|
all: all-before $(BIN) all-after
|
||||||
|
|
||||||
|
|
||||||
|
clean: clean-custom
|
||||||
|
${RM} $(OBJ) $(BIN)
|
||||||
|
|
||||||
|
$(BIN): $(OBJ)
|
||||||
|
$(CPP) $(LINKOBJ) -o main2-gcc.exe $(LIBS)
|
||||||
|
|
||||||
|
check_tmp:
|
||||||
|
@$(CHK_DIR_EXISTS) "" $(MKDIR) "tmp"
|
||||||
|
|
||||||
|
Factory.o: Factory.cpp
|
||||||
|
$(CPP) -c main2.cpp -o main2.o $(CXXFLAGS)
|
||||||
|
|
||||||
|
|
187
test/Longevity/main2.cpp
Executable file
187
test/Longevity/main2.cpp
Executable file
|
@ -0,0 +1,187 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The Loki Library
|
||||||
|
// Copyright (c) 2005 by Curtis Krauskopf
|
||||||
|
// Copyright (c) 2005 by Peter Kuemmel
|
||||||
|
//
|
||||||
|
// Code covered by the MIT License
|
||||||
|
// The authors make no representations about the suitability of this software
|
||||||
|
// for any purpose. It is provided "as is" without express or implied warranty.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// This is an example of using the SetLongevity function for both
|
||||||
|
// singletons and globally and locally defined dynamically allocated
|
||||||
|
// objects.
|
||||||
|
//
|
||||||
|
// The program defines three classes: Example, Keyboard and Log.
|
||||||
|
//
|
||||||
|
// The purpose of the Example class is to send a message to cout
|
||||||
|
// when an Example object is being destroyed.
|
||||||
|
//
|
||||||
|
// The Keyboard class is a singleton.
|
||||||
|
//
|
||||||
|
// The Log class is also a singleton.
|
||||||
|
//
|
||||||
|
// The pGlobal object is deleted using an adapter functor to
|
||||||
|
// customize Example's destruction (see destGlobal()).
|
||||||
|
// The glue that binds the adapter functor (above) with Loki's
|
||||||
|
// SetLongevity function is:
|
||||||
|
//
|
||||||
|
// Loki::Private::Adapter<Example>exampleAdapter = {&destGlobal};
|
||||||
|
// SetLongevity(pGlobal, globalPriority, exampleAdapter);
|
||||||
|
//
|
||||||
|
// An alternative Loki-compatible way of destroying pGlobal (without
|
||||||
|
// defining a global static functor) is to use the default parameter
|
||||||
|
// on SetLongevity:
|
||||||
|
//
|
||||||
|
// Example *pLocal = new Example("Destroying local Example");
|
||||||
|
// SetLongevity(pLocal, localPriority);
|
||||||
|
//
|
||||||
|
// The parameters passed by the user on main define the longevity values
|
||||||
|
// for (respectively):
|
||||||
|
// 1) The global object
|
||||||
|
// 2) The local object
|
||||||
|
// 3) The Keyboard singleton
|
||||||
|
// 4) The Log singleton
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// longevity 1 2 3 4
|
||||||
|
// longevity 40 30 20 10
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "loki/Singleton.h" // for Loki::SingletonHolder
|
||||||
|
|
||||||
|
using namespace std; // okay for small programs
|
||||||
|
using namespace Loki; // okay for small programs
|
||||||
|
|
||||||
|
// These globals allow the priority for each object to be
|
||||||
|
// set in main() but used anywhere in the program.
|
||||||
|
int globalPriority;
|
||||||
|
int localPriority;
|
||||||
|
int keyboardPriority;
|
||||||
|
int logPriority;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// A generic example class that stores and echoes a const char.
|
||||||
|
//
|
||||||
|
class Example
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Example(const char * s)
|
||||||
|
{
|
||||||
|
msg = s;
|
||||||
|
};
|
||||||
|
virtual ~Example()
|
||||||
|
{
|
||||||
|
echo(msg);
|
||||||
|
}
|
||||||
|
void echo(const char *s)
|
||||||
|
{
|
||||||
|
cout << s << endl;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
const char *msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// A singleton Keyboard object derived from the Example class.
|
||||||
|
// Its longevity is set by the user on the command line.
|
||||||
|
//
|
||||||
|
class Keyboard : public Example
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Keyboard() : Example("Destroying Keyboard")
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
inline unsigned int GetLongevity(Keyboard *)
|
||||||
|
{
|
||||||
|
return keyboardPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef SingletonHolder<Keyboard, CreateUsingNew, SingletonWithLongevity> keyboard;
|
||||||
|
|
||||||
|
|
||||||
|
// A singleton Log object derived from the Example class.
|
||||||
|
// Its longevity is set by the user on the command line.
|
||||||
|
//
|
||||||
|
class Log : public Example
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Log() : Example("Destroying Log")
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
inline unsigned int GetLongevity(Log *)
|
||||||
|
{
|
||||||
|
return logPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef SingletonHolder<Log, CreateUsingNew, SingletonWithLongevity> log;
|
||||||
|
|
||||||
|
|
||||||
|
// Instantiate a global Example object. It's not a singleton
|
||||||
|
// but because it's instantiated with new (and therefore it isn't
|
||||||
|
// automatically destroyed) it can use the SetLongevity template function.
|
||||||
|
// Its longevity is determined by the user on the command line.
|
||||||
|
//
|
||||||
|
Example* pGlobal( new Example("Destroying global Example") );
|
||||||
|
|
||||||
|
// destGlobal() is called when the pGlobal object needs to be destroyed.
|
||||||
|
static void destGlobal()
|
||||||
|
{
|
||||||
|
cout << "Going to delete pGlobal\n";
|
||||||
|
delete pGlobal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void help(const char *s)
|
||||||
|
{
|
||||||
|
cout << "To use:\n";
|
||||||
|
cout << s << " par1 par2 par3 par4\n";
|
||||||
|
cout << " where each par is a number that represents the object's ";
|
||||||
|
cout << " longevity:\n";
|
||||||
|
cout << " par1: global object\n";
|
||||||
|
cout << " par2: local object\n";
|
||||||
|
cout << " par3: keyboard singleton\n";
|
||||||
|
cout << " par4: log singleton\n";
|
||||||
|
cout << "Example: " << s << " 1 2 3 4" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc != 5)
|
||||||
|
{
|
||||||
|
help(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
globalPriority = atoi(argv[1]);
|
||||||
|
localPriority = atoi(argv[2]);
|
||||||
|
keyboardPriority = atoi(argv[3]);
|
||||||
|
logPriority = atoi(argv[4]);
|
||||||
|
|
||||||
|
// Use an adapter functor to tie the destGlobal function to the
|
||||||
|
// destruction priority for pGlobal.
|
||||||
|
Loki::Private::Adapter<Example> exampleAdapter = { &destGlobal };
|
||||||
|
SetLongevity(pGlobal, globalPriority, exampleAdapter);
|
||||||
|
|
||||||
|
// Use Loki's private Deleter template function to destroy the
|
||||||
|
// pLocal object for a user-defined priority.
|
||||||
|
Example *pLocal = new Example("Destroying local Example");
|
||||||
|
SetLongevity<Example, void (*)(Example*)>(pLocal, localPriority, &Loki::Private::Deleter<Example>::Delete);
|
||||||
|
|
||||||
|
// Make the global and local objects announce their presense.
|
||||||
|
pGlobal->echo("pGlobal created during program initialization.");
|
||||||
|
pLocal->echo("pLocal created after main() started.");
|
||||||
|
|
||||||
|
// Instantiate both singletons by calling them...
|
||||||
|
log::Instance().echo("Log singleton instantiated");
|
||||||
|
keyboard::Instance().echo("Keyboard singleton instantiated");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
if not exist tmp\ mkdir tmp
|
if not exist tmp\ mkdir tmp
|
||||||
|
|
||||||
|
|
||||||
|
:: main.cpp
|
||||||
|
|
||||||
cl -c -Zm200 -O2 -DNDEBUG -MT -EHsc -GR -W0 -wd4710 -I"." -I"..\..\include" -Fotmp\ main.cpp
|
cl -c -Zm200 -O2 -DNDEBUG -MT -EHsc -GR -W0 -wd4710 -I"." -I"..\..\include" -Fotmp\ main.cpp
|
||||||
|
|
||||||
if not defined LOKI_MSVC_NOLIB (
|
if not defined LOKI_MSVC_NOLIB (
|
||||||
|
@ -11,3 +14,18 @@ link /NOLOGO /SUBSYSTEM:CONSOLE /incremental:no /OUT:"main-msvc.exe" ..\..\lib\l
|
||||||
link /NOLOGO /SUBSYSTEM:CONSOLE /incremental:no /OUT:"main-msvc.exe" tmp\main.obj ..\..\lib\SmallObj.obj ..\..\lib\Singleton.obj
|
link /NOLOGO /SUBSYSTEM:CONSOLE /incremental:no /OUT:"main-msvc.exe" tmp\main.obj ..\..\lib\SmallObj.obj ..\..\lib\Singleton.obj
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
:: main2.cpp
|
||||||
|
|
||||||
|
cl -c -Zm200 -O2 -DNDEBUG -MT -EHsc -GR -W0 -wd4710 -I"." -I"..\..\include" -Fotmp\ main2.cpp
|
||||||
|
|
||||||
|
if not defined LOKI_MSVC_NOLIB (
|
||||||
|
|
||||||
|
link /NOLOGO /SUBSYSTEM:CONSOLE /incremental:no /OUT:"main2-msvc.exe" ..\..\lib\loki.lib tmp\main2.obj
|
||||||
|
|
||||||
|
) else (
|
||||||
|
|
||||||
|
link /NOLOGO /SUBSYSTEM:CONSOLE /incremental:no /OUT:"main2-msvc.exe" tmp\main2.obj ..\..\lib\SmallObj.obj ..\..\lib\Singleton.obj
|
||||||
|
|
||||||
|
)
|
||||||
|
|
|
@ -44,7 +44,8 @@ sub-OrderedStatic: FORCE
|
||||||
|
|
||||||
sub-Longevity: FORCE
|
sub-Longevity: FORCE
|
||||||
cd Longevity && \
|
cd Longevity && \
|
||||||
$(MAKE) -f $(MAKEFILE)
|
$(MAKE) -f $(MAKEFILE) && \
|
||||||
|
$(MAKE) -f $(MAKEFILE)2
|
||||||
@cd ..
|
@cd ..
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
Loading…
Reference in a new issue