single(ton) interface

W

werasm

Hi all,

I have had the following problem in the past and am interested in
what
various (other) solutions exist to solve this:

- Code requiring services dictate an interface to the services
required.
- It only requires one instance to provide those services.
- Services are only realized/bound at runtime.

A typical example of this is an AbstractFactory:

A library requires the services of the factory to build the range of
products
that it requires. How is concrete instance of this factory realized?

Conservatively we in the past used this mechanism:

class Factory
{
public:
static void setConcreteFactory( Factory& impl );
static Factory* get(); //or instance(), if you like
virtual std::auto_ptr<X> makeX() const = 0;
//etc...
protected:
~Factory();
private:
static Factory* impl_;
};

Looking at this, I realized it is not far from this:

//NOTE!!! Only one instance of implementation exist. IsA Singleton
interface!
class Factory
{
public:
static Factory* get(); //or instance(), if you like
virtual std::auto_ptr<X> makeX() const = 0;
//etc...

protected:
Factory( Factory& impl );
~Factory();

private:
static Factory* interface_;
};

Where get and the constructor would typically be implemented like
this:

Factory* Factory::get()
{
assert( interface_ ); //Could use less crude mechanism...
return interface_;
}

//We only want one instance
Factory::Factory( Factory & impl )
{
assert( interface_ == 0 ); //Only one instance :)
interface_ = &impl;
}
Factory::~Factory(){ interface_ = 0; }

This (lets call it) pattern, is easy to generalize like this:

template <class T>
class SingleInterface
{
public:
static T* get();

protected:
SingleInterface( T& impl );
~SingleInterface();

private:
static SingleInterface* interface_;
};

class Factory : public SingleInterface<Factory>
{
public:
virtual std::auto_ptr<X> makeX() const = 0;

protected:
Factory( Factory& ); //Base encapsulate rules and indicates
intent?
~Factory();
};

What other solutions do you have to this, and what is your critic? :)

Regards,

Werner
 
W

werasm

werasm said:
template <class T>
class SingleInterface
{
public:
static T* get();

protected:
SingleInterface( T& impl );
~SingleInterface();

private:
static SingleInterface* interface_;

This should read...

static T* interface_;
 
A

anon

werasm said:
This should read...

static T* interface_;

I just noticed something here. If you use like this, you can get a crash
(forgot the name of this, its in the faq). You should rather do like this:

static T* interface_()
{
T* interface_;
return interface_;
}
 
T

tragomaskhalos

Hi all,

I have had the following problem in the past and am interested in
what various (other) solutions exist to solve this:

[Singleton and Factory stuff snipped]

Werner

"Modern C++ Design" by Andrei Alexandrescu has beautiful
implementations of both Factory and Singleton. The author has created
a library called Loki that contains the code he describes in this
book, so you could try googling for that. I recommend the book in any
case, it's truly mind-expanding stuff.
 
A

anon

werasm said:
> werasm wrote:
>
>
> This should read...
>
> static T* interface_;
>

anon wrote:



Yes, this would certainly give you a crash :). I think you should
reread.

No, the point was to use interface_() instead of interface_

Using uninitialized interface_ will give you crash as well. What I was
looking was this:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

I had a singleton template similar to your, when one day (when my
compiler was upgraded) my singleton started causing seg faults.
 
W

werasm

anon wrote:

No, the point was to use interface_() instead of interface_

Using uninitialized interface_ will give you crash as well. What I was
looking was this:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

Accepted. In that case this is how it would look.


template <class T>
class SingleInterface
{
public:
static T* get();

protected:
SingleInterface( T& impl );
~SingleInterface();

private:
enum eAction{ eCreate, eDestroy, eGet };
static T* doAction( eAction, SingleInterface* impl = 0 );
};

template <class T>
SingleInterface<T>::SingleInterface( T& impl )
{
SingleInterface::doAction( eCreate, &impl );
}

template <class T>
SingleInterface<T>::~SingleInterface()
{
SingleInterface::doAction( eDestroy );
}

template <class T>
T* SingleInterface<T>::doAction( eAction action, SingleInterface*
impl )
{
static SingleInterface* inst( 0 );
if( action == eGet )
{
assert( inst );
return inst;
}
else if( action == eCreate )
{
assert( inst == 0 );
inst = impl;
return inst;
}
else
{
assert( action == eDestroy );
assert( inst );
inst = 0;
return inst;
}
}

template <class T>
T* SingleInterface<T>::get()
{
return SingleInterface::doAction( eGet );
}

BTW, I've only used AbstractFactory as an example of an interface
that
library code uses where it is not aware of the actual implementation
at compile time. There are many other examples (especially in
libraries)
where interfaces are not aware of there implementation, and they
specifically only want one instance of an implementation. I suppose
one could have a factory with a singleton creation policy. I'd look
into that. This does seem to solve the problem at hand though. Thanks
Anon for the FAQ. I have read it prior but in this case one needs the
instance
for previous comparison, hence my oversight.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top