Bit Byter ha scritto:
I want to write a (singleton) container for instances of my class
templates, however, I am not too sure on how to:
1). Store the instances
2). How to write the acccesor method (instance()) to retrieve an
instance of particular template
3). What type to return an instance as ..
Assuming I have the following code:
class template
template <class T1, class T2>
class MyTree
{
T1 foo(const T2& a1);
T2 foobar(const T1& a1, const T2& a2);
};
// Notes
// Instance prototype not completed (see question 2 and 3)
// Ideally, when an instance of a particular class is requested, if it
dosen't yet exist, then an
// instance is created and stored in the 'repository'
class Container
{
instance();
};
//Main.cpp
int main(int argc, char* argv[])
{
Container c;
MyTree<double, int> * t1 = c.instance(/*some args here*/);
MyTree<string, double> *t2 = c.instance(/*some args here*/);
}
Last but not the least, I want to be able to treat objects returned by
the instance() method, in a generic way (i.e. in this example, I want
to be able to treat them generically, as trees). Should I use
inheritance (i.e. the class template inherits from a base Tree class)
like this:
template <class T1, class T2>
class MyTree : public Tree
{
T1 foo(const T2& a1);
T2 foobar(const T1& a1, const T2& a2);
};
or is there a better way?
Hi,
I don't know exactly what you want to do, so there might be better
solutions...
But they way you've put it, I guess using something like boost::any
should do what
you want. Check the code below.
Hope it helps a little.
Bye,
Francesco
#include <vector>
#include <boost/any.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace boost;
//------------------------------------------------------------
class CObjBase
{
public:
virtual ~CObjBase() {}
virtual any DoSome( any const & ) = 0;
virtual any DoOther( any const & inArg1,
any const & inArg2 ) = 0;
virtual bool IsOfType( std::type_info const *,
std::type_info const * ) = 0;
};
//------------------------------------------------------------
template< typename T1, typename T2 >
class CObjConcrete : public CObjBase
{
public:
any DoSome( any const & inArg1 )
{
T2 obj = any_cast< T2 >( inArg1 ); // use object
std::cout << "-------\n";
std::cout << "Arg1: " << obj << std::endl;
return T1(); // return whatever;
}
any DoOther( any const & inArg1, any const & inArg2 )
{
T1 obj1 = any_cast< T1 >( inArg1 );
T2 obj2 = any_cast< T2 >( inArg2 );
std::cout << "-------\n";
std::cout << "Arg1 : " << obj1 << std::endl;
std::cout << "Arg2 : " << obj2 << std::endl;
return obj2;
}
bool IsOfType( std::type_info const * inT1Ptr,
std::type_info const * inT2Ptr )
{
if( *inT1Ptr == typeid( T1 ) and *inT2Ptr == typeid( T2 ) )
return true;
else
return false;
}
};
//------------------------------------------------------------
class CFactory
{
public:
static CFactory & GetInstance()
{ static CFactory sObj; return sObj; }
template< typename T1, typename T2 >
shared_ptr< CObjBase > Get();
private:
typedef std::vector< shared_ptr< CObjBase > > CRegister;
CRegister mRegister;
CFactory() {}
CFactory( CFactory const & );
~CFactory() {}
CFactory & operator=( CFactory const & );
};
CFactory & Factory() { return CFactory::GetInstance(); }
//------------------------------------------------------------
template< typename T1, typename T2 >
shared_ptr< CObjBase > CFactory::Get()
{
CRegister::iterator iter = std::find_if(
mRegister.begin(),
mRegister.end(),
bind( &CObjBase::IsOfType, _1, &typeid( T1 ), &typeid( T2 ) )
);
if( iter == mRegister.end() )
{
std::cout << "CREATING\n";
shared_ptr< CObjBase > ptr( new CObjConcrete< T1, T2 > );
mRegister.push_back( ptr );
return ptr;
}
else
{
std::cout << "REUSING\n";
return *iter;
}
}
//------------------------------------------------------------
int main()
{
Factory().Get< int, double >()->DoSome( 13.56 );
Factory().Get< std::string, int >()->DoOther(
std::string( "ola" ),
100
);
Factory().Get< int, double >()->DoSome( 67.67 );
Factory().Get< std::string, int >()->DoOther(
std::string( "TEST" ),
900
);
std::cin.get();
}
//end code
This is exactly what I was looking for. I have a quick question about