I have just discovered the following jewel in the code (the example is very simplified, but the logic is the same):
template <class T>
class garbage_bin
{
private:
garbage_bin<T>(void)
{
}
static garbage_bin<T>* pinstance;
public:
static garbage_bin<T>& instance()
{
if(pinstance == NULL)
{
pinstance = new garbage_bin<T>();
}
return *pinstance;
}
void empty()
{
for(size_t i=0; i<items.size(); i++)
{
free (items[i]);
}
}
void throwIn(T item)
{
items.push_back(item);
}
vector<T> items;
};
and then somewhere in the code (this is just ONE example ... there are thousands like this):
char* r = strdup(src);
garbage_bin<char*>::instance().throwIn(r);
and later somewhere in the code, right before the exit ...
garbage_bin<char*>::instance().empty();
garbage_bin<molecules*>::instance().empty();
garbage_bin<CDatabaseUsers*>::instance().empty();
and so on ...
so as we can see, this implements a garbage bin class, in which you can "throw in" all kind of objects, and at a later stage to avoid the memory leaks you "empty" the garbage bin. But here comes the big bottleneck: In order for this to work properly, you need to know all the classes for which this garbage bin was instantiated in order to empty them...
The most direct solution I was thinking of is to create a map of typeid calls for the instantiations, and assign the garbage_bin<T>::instance() to the name however an ancient compiler decided that he does not like this approach.
Obviously, I can make a search through the code to find all the templatizations, but I'm wondering ... is there a simpler way to do this?
Garbage bin bin!
class garbage_bin_base;
class garbage_bin_bin {
public:
void throwIn(garbage_bin_base* rubbish) { items.push_back(rubbish); }
void empty() { for (auto item: items) item->empty(); }
private:
vector<garbage_bin_base*> items;
};
class garbage_bin_base {
public:
virtual empty() = 0;
garbage_bin_base() { garbage_bin_bin::instance().throwIn(this); }
};
template <typename T>
class garbage_bin : public garbage_bin_base {
};
You could add a registry for things to be deleted:
Registry registry;
// ...
if (pinstance == NULL)
{
pinstance = new garbage_bin<T>();
registry.add<T>();
}
// ...
registry.clear_all();
For example:
class Registry
{
struct Base
{
virtual ~Base() {}
virtual void clear() = 0;
};
template <typename T> struct Derived : Base
{
virtual void clear() { garbage_bin<T*>::instance().empty(); }
};
std::vector<std::unique_ptr<Base>> targets;
public:
void clear_all() { for (auto & p : targets) { p->clear(); } }
template <typename T> void add()
{
targets.emplace_back(new Derived<T>);
}
};
I would rather replace garbage_bin<T> with std::vector<std::unique_ptr<T>> (or, maybe, std::vector<std::shared_ptr<T>>).
If you want to restrict the interface, then reimplement garbage_bin<T> as a wrapper around std::vector<std::unique_ptr<T>>. In this way, you probably don't need the empty method since the destructors of std::vector and std::unique_ptr will clean-up after themselves. However, if you want to empty the bin before destruction, then implement empty just calling std::vector::clear.
I understand that this is not exactly the simplest thing to do (because the OP says there are "thousands" of places to be changed) but a refactoring of this bad design is clearly needed.
Related
I am just thinking about a way to check an object to be valid in a automated way.
I have a couple of hardware related objects (like class A), which can be deleted by external (physical) events.
To detect this I have used shared/weak pointer. But now I am struggling with the checking of the weak pointer. Since this is done in the same way for each member function for many objects, I am currently searching for a way to do this with less redundant code.
In addition I am writing a library and do not want the user to handle this (simply return the weak pointer to the user to handle it by himself is therefor no option)
My best guess is shown below. My problem is, I could not find a way to generate the member functions (func1, and many more ...) automatically within the template. Doing it by myself would result in lot of redundant code for every member function to be validated (and there are a lot)
Each member function of A (and many more other objects) shall be wrapped by a function doing the validation shown below. This is same for all member functions and done for many classes which can be used as type for the Validator.
Does anyone has an idea how to solve this? Maybe there are other (better) ways to solve this.
Many thanks for your help.
Some constraints:
Only C++11 possible,
No exceptions
class A {
public:
void func1() {}
//many more functions
};
template<typename T>
class Validator
{
//has to be done for all functions of A
void func1()
{
if (!wptr.expired())
{
wptr.lock()->func1();
}
else
errorHandling();
}
private:
std::weak_ptr<T> wptr;
void errorHandling() {}
};
I would protect the full user function call:
class A {
public:
void func1() {}
//many more functions
};
template <typename T>
class Validator
{
public:
#if 1 // template way, but no-expressive signature
template <typename F>
void do_job(F f)
#else // type-erasure way, expressive, but with some overhead
void do_job(std::function<void (T&)> f)
#endif
{
auto t = wptr.lock();
if (t) {
f(*t);
} else {
errorHandling();
}
}
private:
void errorHandling();
private:
std::weak_ptr<T> wptr;
};
So user might chain call:
Validator<A> val;
val.do_job([](A& a)
{
a.func1();
a.func2();
});
If the caller can live with clunky syntax you can use member function pointers:
#include <memory>
#include <iostream>
class A {
public:
void func1() {
std::cout << "hello func1\n";
}
};
template<typename T>
class Validator
{
public:
Validator(std::shared_ptr<T> p) : wptr(p) {}
template <typename MemFun>
void call(MemFun mf) {
if (!wptr.expired())
{
(wptr.lock().get()->*mf)();
}
else
errorHandling();
}
private:
std::weak_ptr<T> wptr;
void errorHandling() {}
};
int main() {
auto x = std::make_shared<A>();
Validator<A> v{x};
v.call(&A::func1);
}
I created a singleton pattern as a template class.
template <typename T>
class TemplateSingleton
{
protected:
TemplateSingleton() { }
virtual ~TemplateSingleton() { }
public:
static T * GetInstance()
{
if (m_pInstance == NULL)
m_pInstance = new T;
return m_pInstance;
};
static void FreeInstance()
{
if (m_pInstance != NULL)
{
delete m_pInstance;
m_pInstance = NULL;
}
};
private:
static T * m_pInstance;
};
template <typename T> T * TemplateSingleton<T>::m_pInstance = NULL;
And use inherited from child class.
This class can be used as a singleton by inheriting a template, or as a generic class if not inherited.
#define MAX_COUNT 8
class CDataHandler : public TemplateSingleton<CDataHandler>
{
public:
CDataHandler();
~CDataHandler();
...
private:
CDataObj m_clDataObj[MAX_COUNT]; // CDataObj *m_clDataObj ?
DWORD m_dwDataObjCount;
...
};
class CDataObj
{
public:
CDataObj();
~CDataObj();
...
private:
...
};
The code above is in a DLL, and the program is implemented to call only the instance constructor of CDataHandler.
And my program crashes and quits.
By the way, if I change CDataObj member variable from array to pointer, it works fine.
(In this case, new in the constructor of the CDataHandler, and delete in the destructor.)
Is there something wrong with this code?
Addition)
constructor and destructor code for CDataHandler :)
CDataHandler::CDataHandler()
: m_dwDataObjCount(0)
//, m_clDataObj(NULL)
{
// Do nothing
// m_clDataObj = new CDataObj[MAX_COUNT];
}
CDataHandler::~CDataHandler()
{
//if (m_clDataObj != NULL)
{
for (int i = 0; i < MAX_COUNT; i++)
{
m_clDataObj[i].Close();
}
// delete[] m_clDataObj;
// m_clDataObj = NULL;
}
}
Not sure what is causing your program to crash, but there are two potential problems in the code you posted.
First, you don't know when m_pInstance will be initialised to NULL. If you call GetInstance() during static data initialisation, m_pInstance might not yet be initialised to NULL and thus GetInstance() will return some invalid pointer. Look up "static data initialisation order fiasko" or something like this, there is a lot of information on this.
To avoid this, you can use local static variables, along the lines of:
T* GetInstance()
{
static T* t = new T{};
return t;
}
Second, you use a template for your singleton. That's okay, but you have to take care: If the definition of the class is available to more than one compilation unit, each of these compilation units will instantiate their own singleton, leaving you with multiple different instances depending on from which compilation unit you are accessing them.
To solve this, you can use extern template for a certain T in the DLL to tell others they should not instantiate this template specialisation and then compile an explicit template instantiation into the DLL to provide the implementation for everyone.
I want to implement a class hierarchy for object dispatching. Different classes dispatch different elements, and each class can dispatch its element represented as different data types.
It is better understood through a (faulty) example. This is what I would like to have if virtual function templating was allowed:
class Dispatcher {
template <class ReturnType>
virtual ReturnType getStuffAs();
};
So that I can implement subclasses as:
class CakeDispatcher : public Dispatcher {
template <>
virtual Recipe getStuffAs(){ ... }
template <>
virtual Baked getStuffAs(){ ... }
};
class DonutDispatcher : public Dispatcher {
template <>
virtual Frozen getStuffAs(){ ... }
template <>
virtual Baked getStuffAs(){ ... }
}
So that I can do the following later on:
void function( Dispatcher * disp ) {
// Works for Donut and Cake, but result will be a different Baked object
Baked b = disp->getStuffAs<Baked>();
// works if disp points to a DonutDispatcher
// fails if it is a CakeDispatcher
// can be compiling/linking time error or runtime error. I don't care
Frozen f = disp->getStuffAs<Frozen>();
}
Requirements/constraints:
All possible return types are not known beforehand. That's why I "need" templates.
Each class can provide just some return types.
Classes must have a common ancestor, so that I can store objects through a pointer to parent class and invoke functions through this pointer.
EDIT: I CAN'T use C++11 features, but I CAN use boost library.
Things I've thought about, but are not a solution:
Obviously, virtual template functions
Curiously Recurring Template Pattern: breaks the condition of common ancestor
Using some kind of traits class containing the functionality of children classes, but it does not work because a non-virtual implementation in the parent class does not have access to this information
I could maybe store some typeid info in the parent class, passed by children on construction. This makes possible for the non-virtual parent dispatching method to dynamic-cast itself to the children type... but it appears to be ugly as hell, and I don't know if this can cause some kind cycle-referencing problem.
class Dispatcher {
private:
typeid(?) childType;
public:
Dispatcher(typeid childT) : childType(childT) {}
// NOT VIRTUAL
template <class ReturnType>
ReturnType getStuffAs()
{
// or something equivalent to this cast, which I doubt is a correct expression
return dynamic_cast<childType *>(this)->childGetStuffAs<ReturnType>();
}
};
Then child classes would implement childGetStuffAs functions, which are not virtual too.
I've read like 5-10 related questions, but none of the provided solutions seems to fit this problem.
Can any of you come up with a better solution?
Is there a standard pattern/technique for solving this problem?
EDIT: The real problem
In the real problem, I have physical models with properties that can be represented in multiple ways: functions, matrices, probability distributions, polynomials, and some others (for example, a non-linear system can be represented as a function but not as a a matrix, while a linear system can be transformed to both).
There are also algorithms which can use those models indistinctly, but they could require specific representations for some model features. That's the reason for the "getStuffAs" function. The whole think is a bit complicated --too much to explain it here properly--, but I can guarantee that in this context the interface is well defined: input, computation and output.
My intention was to make this possible assuming that the number of possible representations is fully defined beforehand, and making it possible to transform the products to already existing types/classes that cannot be modified.
However, i'm starting to realize that this is, indeed, not possible in a simple way --I don't want to write a library just for this problem.
#include <cstdio>
// as a type identifier
struct stuff {
virtual void foo() {}
};
template <typename T>
struct stuff_inh : stuff {
};
struct Dispatcher {
template <typename T>
T* getStuffAs() {
return (T*)((getStuffAsImpl( new stuff_inh<T>() )));
}
virtual void* getStuffAsImpl(void*) = 0;
virtual void type() {printf("type::dispatcher\n");}
};
struct Cake : public Dispatcher {
void* getStuffAsImpl(void* p) {
stuff* s = static_cast<stuff*>(p);
printf("cake impl\n");
if (dynamic_cast<stuff_inh<Cake>*>(s) == NULL) {
throw "bad cast";
}
return (void*)(new Cake());
}
virtual void type() {printf("type::Cake\n");}
};
struct Rabbit : public Dispatcher {
void* getStuffAsImpl(void* p) {
stuff* s = static_cast<stuff*>(p);
printf("rabbit impl\n");
if (dynamic_cast<stuff_inh<Rabbit>*>(s) != NULL) {
return (void*)(new Rabbit());
}
else if (dynamic_cast<stuff_inh<Cake>*>(s) != NULL) {
return (void*)(new Cake());
}
else {
throw "bad cast";
}
}
virtual void type() {printf("type::Rabbit\n");}
};
void foo(Dispatcher* d) {
d->getStuffAs<Cake>()->type();
d->getStuffAs<Rabbit>()->type();
}
int main() {
Rabbit* r = new Rabbit;
foo(r);
Cake* c = new Cake;
foo(c);
}
I an not sure about the correctness of this ugly solution, may it be helpful for you. >_<
deletion of resource is not coded for a clearer look.
My solution is a combination of recurring template and diamond inheritance.
At least it's working. :)
#include <iostream>
class Dispatcher
{
public:
template<class T>
T getStuff()
{
return T();
}
};
template<class T>
class Stuffer : public Dispatcher
{
public:
template<class TT=T>
TT getStuff(){
return reinterpret_cast<TT>(this);
}
};
class Cake{
public:
Cake(){}
void print()
{
std::cout << "Cake" << std::endl;
}
};
class Recipe
{
public:
Recipe(){}
void print()
{
std::cout << "Recipe" << std::endl;
}
};
class CakeRecipe : public Stuffer<Cake>, public Stuffer< Recipe >
{
public:
};
int main()
{
Dispatcher* cr = reinterpret_cast<Dispatcher*>(new CakeRecipe());
cr->getStuff<Cake>().print();
cr->getStuff<Recipe>().print();
getchar();
return 1;
}
I have a user interface with a tree view on the left, and a viewer on the right (a bit like an email client). The viewer on the right displays the detail of whatever I have selected in the tree on the left.
The user interface has "add", "edit" and "delete" buttons. These buttons act differently depending on what "node" in the tree is selected.
If I have a node of a particular type selected, and the user clicks "edit", then I need to open the appropriate edit dialog for that particular type of node, with the details of that node.
Now, there's a lot of different types of node and implementing a visitor class feels a bit messy (currenty my visitor has about 48 entries....). It does work nicely though - basically for editing a have something like an OpenEditDialog class that inherits the visitor, and opens the appropriate edit dialog:
abstractTreeNode->accept(OpenEditDialog());
The problem is I have to implement the abstract visitor class for every "action" I want to perform on the node and for some reason I can't help thinking I'm missing a trick.
The other way could of been to implement the functions in the nodes themselves:
abstractTreeNode->openEditDialog();
I'm ording the node around a bit here, so maybe this is better:
abstractTreeNode->editClickedEvent();
I can't help but think this is polluting the node though.
I did think of a third way that I've not given that much thought yet. I could have a templated wrapper class that gets added to the tree instead which allows me to perhaps call free-functions to perform whatever actions, so I guess as it acts as a go between for nodes and interface:
(pseudo code off the top of my head just to give an idea):
template <class T>
TreeNode(T &modelNode)
{
m_modelNode = modelNode;
}
template <>
void TreeNode<AreaNode>::editClickedEvent()
{
openEditDialog(m_modelNode); // Called with concrete AreaNode
}
template <>
void TreeNode<LocationNode>::editClickedEvent()
{
openEditDialog(m_modelNode); // Called with concrete LocationNode
}
etc..
So this is effectively extending the nodes but in a different way to using the visitor and it seems a little bit neater.
Now before I go ahead and take the plunge using one of these methods, I thought it'd be wise to get some input.
Thanks! I hope all this makes some sense..
EDIT:
I've mocked up the templated wrapper idea..
class INode
{
public:
virtual ~INode() {}
virtual void foo() = 0;
};
class AreaNode : public INode
{
public:
AreaNode() {}
virtual ~AreaNode() {}
void foo() { printf("AreaNode::foo\r\n"); }
};
class RoleNode : public INode
{
public:
RoleNode() {}
virtual ~RoleNode() {}
void foo() { printf("RoleNode::foo\r\n"); }
};
class ITreeNode
{
public:
virtual ~ITreeNode() {}
virtual void bar() = 0;
virtual void foo() = 0;
};
template <class T>
class MainViewTreeNode : public ITreeNode
{
public:
MainViewTreeNode() : m_node() {}
virtual ~MainViewTreeNode() {}
void bar() {}
void foo() { m_node.foo(); }
protected:
T m_node;
};
template <>
void MainViewTreeNode<AreaNode>::bar()
{
printf("MainViewTreeNode<AreaNode>::bar\r\n");
}
template <>
void MainViewTreeNode<RoleNode>::bar()
{
printf("MainViewTreeNode<RoleNode>::bar\r\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
MainViewTreeNode<RoleNode> role;
MainViewTreeNode<AreaNode> area;
std::list<ITreeNode*> nodes;
nodes.push_back(&role);
nodes.push_back(&area);
std::list<ITreeNode*>::iterator it = nodes.begin();
for (; it != nodes.end(); ++it)
{
(*it)->foo();
(*it)->bar();
}
getchar();
return 0;
}
Thanks.
Visitor is useful when you have many operations and few types. If you have many types, but few operations, use normal polymorphism.
Instead of using m_node.foo(), what you should do is static inheritance. This is basically your "template wrapper" idea, but it's a well-established pattern.
class ITreeNode
{
public:
virtual ~ITreeNode() {}
virtual void bar() = 0;
virtual void foo() = 0;
};
template <class T>
class MainViewTreeNode : public ITreeNode
{
public:
MainViewTreeNode() : m_node() {}
virtual ~MainViewTreeNode() {}
void bar() {}
void foo() { m_node.foo(); }
protected:
T m_node;
};
becomes
class ITreeNode
{
public:
virtual ~ITreeNode() {}
virtual void bar() = 0;
virtual void foo() = 0;
};
template <class T>
class MainViewTreeNode : public ITreeNode
{
public:
MainViewTreeNode() {}
virtual ~MainViewTreeNode() {}
void bar() { T::bar(); }
void foo() { T::foo(); }
};
class RoleNode : public MainViewTreeNode<RoleNode> {
void bar() { std::cout << "Oh hai from RoleNode::bar()! \n"; }
void foo() { std::cout << "Oh hai from RoleNode::foo()! \n"; }
};
Of course, if you already have regular inheritance in the mix, why not just use that? There's not going to be any easier solution than normal polymorphism here. It works well when the number of types is high and the number of operations is low. Perhaps the flaw in your design is how many types you have.
Such problems are, unfortunately, all too common with C++ and statically typed OO languages in general. I recently stumbled into this article which describes how to implement double dispatch with a custom-made lookup table.
I can see a similar approach working here. Basically, you build a table of function wrappers of the type Entry below:
class EntryBase {
public:
virtual bool matches(TreeNode const &node) const = 0;
virtual void operator()(TreeNode &node) const = 0;
};
template<typename NodeType, typename Functor>
class Entry : public EntryBase {
Functor d_func;
public:
Entry(Functor func) : d_func(func) { }
virtual bool matches(TreeNode const &node) const {
return dynamic_cast<NodeType const *>(&node) != 0;
}
virtual void operator()(TreeNode &node) const {
d_func(dynamic_cast<NodeType &>(node));
}
};
Each such table would then represent one type of Visitor (you can do this without Boost too, of course):
class NodeVisitor {
typedef boost::shared_ptr<EntryBase> EntryPtr;
typedef std::vector<EntryPtr> Table;
Table d_entries;
public:
template<typename NodeType, typename Functor>
void addEntry(Functor func) {
EntryPtr entry(new Entry<NodeType, Functor>(func));
d_entries.push_back(entry);
}
void visit(TreeNode &node) {
EntryPtr entry = lookup(node);
if (!entry)
return; // this Visitor doesn't handle this type
(*entry)(node);
}
private:
EntryPtr lookup(TreeNode &node) {
Table::const_iterator iter =
std::find_if(d_entries.begin(), d_entries.end(),
boost::bind(&EntryBase::matches, _1, boost::ref(node)));
if (iter != d_entries.end())
return *iter;
return 0;
}
};
Construction of a table would be something like this:
void addToCompany(CompanyNode &company) { ... }
void addToEmployee(EmployeeNode &employee) { ... }
NodeVisitor nodeAdder;
nodeAdder.addEntry<CompanyNode>(&addToCompany);
nodeAdder.addEntry<EmployeeNode>(&addToEmployee);
After all that work, you could simply write (without any additions to TreeNode or any class that inherits from TreeNode):
nodeAdder.visit(someNode);
The templates ensure that the dynamic_cast always succeeds, so it's quite safe. The largest drawback is, of course, that it's not the fastest in the world. But for opening a dialog, the user is probably the slower factor, so it should be quite fast enough.
I just implemented this visitor in my own project, and it is working like a charm!
Another pattern to consider here is the Command pattern. You make your nodes store a list of commands that all have GetName & Execute methods. When a node is selected you enumerate the collection and call GetName on each command to get the menu items' name and when a menu item is clicked you call Execute. This gives you ultimate flexibility, you can set up the commands when the tree is created or in each node type's constructor. Either way you get to reuse commands accross types and have varying numbers of commands for each type.
Generally though, my experience would suggest that both this and the visitor pattern are probably overkill in this case and simply putting virtual Add, Edit and Delete methods on the base tree node type is the way to go.
I have an application that has several objects (about 50 so far, but growing). There is only one instance of each of these objects in the app and these instances get shared among components.
What I've done is derive all of the objects from a base BrokeredObject class:
class BrokeredObject
{
virtual int GetInterfaceId() = 0;
};
And each object type returns a unique ID. These IDs are maintained in a header file.
I then have an ObjectBroker "factory". When someone needs an object, then call GetObjectByID(). The boker looks in an STL list to see if the object already exists, if it does, it returns it. If not, it creates it, puts it in the list and returns it. All well and good.
BrokeredObject *GetObjectByID(int id)
{
BrokeredObject *pObject;
ObjectMap::iterator = m_objectList.find(id);
// etc.
if(found) return pObject;
// not found, so create
switch(id)
{
case 0: pObject = new TypeA; break;
case 1: pObject = new TypeB; break;
// etc.
// I loathe this list
}
// add it to the list
return pObject;
}
What I find painful is maintaining this list of IDs and having to have each class implement it. I have at least made my consumer's lives slightly easier by having each type hold info about it's own ID like this:
class TypeA : public BrokeredObject
{
static int get_InterfaceID() { return IID_TYPEA; }
int GetInterfaceID() { return get_InterfaceID(); }
};
So I can get an object like this:
GetObjectByID(TypeA::get_InterfaceID());
Intead of having to actually know what the ID mapping is but I still am not thrilled with the maintenance and the potential for errors. It seems that if I know the type, why should I also have to know the ID?
What I long for is something like this in C#:
BrokeredObject GetOrCreateObject<T>() where T : BrokeredObject
{
return new T();
}
Where the ObjectBroker would create the object based on the type passed in.
Has C# spoiled me and it's just a fact of life that C++ can't do this or is there a way to achieve this that I'm not seeing?
Yes, there is a way. A pretty simple even in C++ to what that C# code does (without checking for inheritance though):
template<typename T>
BrokeredObject * GetOrCreateObject() {
return new T();
}
This will work and do the same as the C# code. It is also type-safe: If the type you pass is not inherited from BrokeredObject (or isn't that type itself), then the compiler moans at the return statement. It will however always return a new object.
Singleton
As another guy suggested (credits to him), this all looks very much like a fine case for the singleton pattern. Just do TypeA::getInstance() to get the one and single instance stored in a static variable of that class. I suppose that would be far easier than the above way, without the need for IDs to solve it (i previously showed a way using templates to store IDs in this answer, but i found it effectively is just what a singleton is).
I've read that you will leave the chance open to have multiple instances of the classes. One way to do that is to have a Mingleton (i made up that word :))
enum MingletonKind {
SINGLETON,
MULTITON
};
// Singleton
template<typename D, MingletonKind>
struct Mingleton {
static boost::shared_ptr<D> getOrCreate() {
static D d;
return boost::shared_ptr<D>(&d, NoopDel());
}
struct NoopDel {
void operator()(D const*) const { /* do nothing */ }
};
};
// Multiton
template<typename D>
struct Mingleton<D, MULTITON> {
static boost::shared_ptr<D> getOrCreate() {
return boost::shared_ptr<D>(new D);
}
};
class ImASingle : public Mingleton<ImASingle, SINGLETON> {
public:
void testCall() { }
// Indeed, we have to have a private constructor to prevent
// others to create instances of us.
private:
ImASingle() { /* ... */ }
friend class Mingleton<ImASingle, SINGLETON>;
};
class ImAMulti : public Mingleton<ImAMulti, MULTITON> {
public:
void testCall() { }
// ...
};
int main() {
// both do what we expect.
ImAMulti::getOrCreate()->testCall();
ImASingle::getOrCreate()->testCall();
}
Now, you just use SomeClass::getOrCreate() and it cares about the details. The custom deleter in the singleton case for shared_ptr makes deletion a no-op, because the object owned by the shared_ptr is allocated statically. However, be aware of problems of destruction order of static variables: Static initialization order fiasco
The way I would solve this problem is using what I would call the Static Registry Pattern, which in my mine mind is the C++ version of dependency injection.
Basically you have a static list of builder objects of a type that you use to build objects of another type.
A basic static registry implementation would look like:
template <class T>
class StaticRegistry
{
public:
typedef std::list<T*> Container;
static StaticRegistry<T>& GetInstance()
{
if (Instance == 0)
{
Instance = new StaticRegistry<T>;
}
return *Instance;
}
void Register(T* item)
{
Items.push_back(item);
}
void Deregister(T* item)
{
Items.remove(item);
if (Items.empty())
{
delete this;
Instance = 0;
}
}
typedef typename Container::const_iterator const_iterator;
const_iterator begin() const
{
return Items.begin();
}
const_iterator end() const
{
return Items.end();
}
protected:
StaticRegistry() {}
~StaticRegistry() {}
private:
Container Items;
static StaticRegistry<T>* Instance;
};
template <class T>
StaticRegistry<T>* StaticRegistry<T>::Instance = 0;
An implementation of BrokeredObjectBuilder could look like this:
class BrokeredObjectBuilderBase {
public:
BrokeredObjectBuilderBase() { StaticRegistry<BrokeredObjectBuilderBase>::GetInstance().Register(this); }
virtual ~BrokeredObjectBuilderBase() { StaticRegistry<BrokeredObjectBuilderBase>::GetInstance().Deregister(this); }
virtual int GetInterfaceId() = 0;
virtual BrokeredObject* MakeBrokeredObject() = 0;
};
template<class T>
class BrokeredObjectBuilder : public BrokeredObjectBuilderBase {
public:
BrokeredObjectBuilder(unsigned long interface_id) : m_InterfaceId(interface_id) { }
virtual int GetInterfaceId() { return m_InterfaceId; }
virtual T* MakeBrokeredObject() { return new T; }
private:
unsigned long m_InterfaceId;
};
class TypeA : public BrokeredObject
{
...
};
// Create a global variable for the builder of TypeA so that it's
// included in the BrokeredObjectBuilderRegistry
BrokeredObjectBuilder<TypeA> TypeABuilder(TypeAUserInterfaceId);
typedef StaticRegistry<BrokeredObjectBuilderBase> BrokeredObjectBuilderRegistry;
BrokeredObject *GetObjectByID(int id)
{
BrokeredObject *pObject(0);
ObjectMap::iterator = m_objectList.find(id);
// etc.
if(found) return pObject;
// not found, so create
BrokeredObjectBuilderRegistry& registry(BrokeredObjectBuilderRegistry::GetInstance());
for(BrokeredObjectBuilderRegistry::const_iterator it = registry.begin(), e = registry.end(); it != e; ++it)
{
if(it->GetInterfaceId() == id)
{
pObject = it->MakeBrokeredObject();
break;
}
}
if(0 == pObject)
{
// userinterface id not found, handle this here
...
}
// add it to the list
return pObject;
}
Pros:
All the code that knows about creating the types is seperated out into the builders and the BrokeredObject classes don't need to know about it.
This implementation can be used in libraries and you can control on a per project level what builders are pulled into a project using a number of different techniques.
The builders can be as complex or as simple (like above) as you want them to be.
Cons:
There is a wee bit of infrastructure involved (but not too much).
The flexability of defining the global variables to include what builders to include in your project does make it a little messy to work with.
I find that people find it hard to understand this pattern, I'm not sure why.
It's sometimes not easy to know what is in the static registry at any one time.
The above implementation leaks one bit of memory. (I can live with that...)
The above implementation is very simple, you can extend it in lots of different ways depending on the requirements you have.
Use a template class as the broker.
Make the instance a static member of the function. It will be created on first use and automagically-destroyed when the program exits.
template <class Type>
class BrokeredObject
{
public:
static Type& getInstance()
{
static Type theInstance;
return theInstance;
}
};
class TestObject
{
public:
TestObject()
{}
};
int main()
{
TestObject& obj =BrokeredObject<TestObject>::getInstance();
}
Instead of GetInterfaceId() in the BrokeredObject base class, you could define that pure virtual method:
virtual BrokeredObject& GetInstance()=0;
And in the derived classes you'll return from that method the instance of the particular derived class, if it's already created, if not, you'll first create it and then return it.
It doesn't look like you need the global object to do the management, so why not move everything into the classes themselves?
template <class Type>
class BrokeredObject
{
protected:
static Type *theInstance;
public:
static Type *getOrCreate()
{
if (!theInstance) {
theInstance = new Type();
}
return theInstance;
}
static void free()
{
delete theInstance;
}
};
class TestObject : public BrokeredObject<TestObject>
{
public:
TestObject()
{}
};
int
main()
{
TestObject *obj = TestObject::getOrCreate();
}
If you have RTTI enabled, you can get the class name using typeid.
One question, why are you using a factory rather than using a singleton pattern for each class?
Edit: OK, so you don't want to be locked into a singleton; no problem. The wonderful thing about C++ is it gives you so much flexibility. You could have a GetSharedInstance() member function that returns a static instance of the class, but leave the constructor public so that you can still create other instances.
If you always know the type at compile time there is little point in calling BrokeredObject* p = GetObjectByID(TypeA::get_InterfaceID()) instead of TypeA* p = new TypeA or TypeA o directly.
If you on the other hand don't know the exact type at compile time, you could use some kind of type registry.
template <class T>
BrokeredObject* CreateObject()
{
return new T();
}
typedef int type_identity;
typedef std::map<type_identity, BrokeredObject* (*)()> registry;
registry r;
class TypeA : public BrokeredObject
{
public:
static const type_identity identity;
};
class TypeB : public BrokeredObject
{
public:
static const type_identity identity;
};
r[TypeA::identity] = &CreateObject<TypeA>;
r[TypeB::identity] = &CreateObject<TypeB>;
or if you have RTTI enabled you could use type_info as type_identity:
typedef const type_info* type_identity;
typedef std::map<type_identity, BrokeredObject* (*)()> registry;
registry r;
r[&typeid(TypeA)] = &CreateObject<TypeA>;
r[&typeid(TypeB)] = &CreateObject<TypeB>;
Each new class could of course, in any case, be self-registering in the registry, making the registration decentralized instead of centralized.
You should almost certainly be using dependency injection.
Why not this?
template
BrokeredObject* GetOrCreateObject()
{
return new T();
}
My use-case tended to get a little more complex - I needed the ability to do a little bit of object initialization and I needed to be able to load objects from different DLLs based on configuration (e.g. simulated versus actual for hardware). It started looking like COM and ATL was where I was headed, but I didn't want to add the weight of COM to the OS (this is being done in CE).
What I ended up going with was template-based (thanks litb for putting me on track) and looks like this:
class INewTransModule
{
public:
virtual bool Init() { return true; }
virtual bool Shutdown() { return true; }
};
template <typename T>
struct BrokeredObject
{
public:
inline static T* GetInstance()
{
static T t;
return &t;
}
};
template <>
struct BrokeredObject<INewTransModule>
{
public:
inline static INewTransModule* GetInstance()
{
static INewTransModule t;
// do stuff after creation
ASSERT(t.Init());
return &t;
}
};
class OBJECTBROKER_API ObjectBroker
{
public:
// these calls do configuration-based creations
static ITraceTool *GetTraceTool();
static IEeprom *GetEeprom();
// etc
};
Then to ensure that the objects (since they're templated) actually get compiled I added definitions like these:
class EepromImpl: public BrokeredObject<EepromImpl>, public CEeprom
{
};
class SimEepromImpl: public BrokeredObject<SimEepromImpl>, public CSimEeprom
{
};