[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Class templates and singleton container

Bit Byter

11/1/2008 11:02:00 AM

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?
4 Answers

Francesco

11/3/2008 10:54:00 AM

0



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

(2b|!2b)==?

11/3/2008 10:36:00 PM

0

Francesco wrote:
>
> 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

Thanks Francesco,

This is exactly what I was looking for. I have a quick question about
your IsOfType function:

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;
}

You are using 'and' is that in the boost namespace? (I couldnt find it),
or did you simply mean the unary boolean 'and' operator (&&) ?


Francesco

11/4/2008 10:12:00 AM

0



(2b|!2b)==? ha scritto:

> Francesco wrote:
> >
> > 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
>
> Thanks Francesco,
>
> This is exactly what I was looking for. I have a quick question about
> your IsOfType function:
>
> 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;
> }
>
> You are using 'and' is that in the boost namespace? (I couldnt find it),
> or did you simply mean the unary boolean 'and' operator (&&) ?

No, it's not boost stuff, it's standard: just an alternative token to
&&. Check out the standard @ "2.5 Alternative Tokens"...
I believe it's a binary op though... ;-)
Glad I helped, bye,
Francesco

Francesco

11/4/2008 10:39:00 AM

0



(2b|!2b)==? ha scritto:

> Francesco wrote:
> >
> > 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
>
> Thanks Francesco,
>
> This is exactly what I was looking for. I have a quick question about
> your IsOfType function:
>
> 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;
> }
>
> You are using 'and' is that in the boost namespace? (I couldnt find it),
> or did you simply mean the unary boolean 'and' operator (&&) ?

[this might be a double post... sorry in advance]

Anyway, no 'and' is not boost stuff, it's standard c++: it's just an
alternative token to &&.
Check out the standard @ "2.5 Alternative tokens".
I believe it's a binary op though... ;-)
Glad I helped, bye,
Francesco