468,272 Members | 2,146 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,272 developers. It's quick & easy.

Class templates and singleton container

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?
Nov 1 '08 #1
4 2128


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
Nov 3 '08 #2
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 (&&) ?
Nov 3 '08 #3


(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
Nov 4 '08 #4


(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
Nov 4 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Simon Elliott | last post: by
5 posts views Thread by Thomas Matthews | last post: by
6 posts views Thread by Johan Bergman | last post: by
9 posts views Thread by Jon Wilson | last post: by
21 posts views Thread by Jon Slaughter | last post: by
7 posts views Thread by ankitjain.bvcoe | last post: by
12 posts views Thread by keepyourstupidspam | last post: by
reply views Thread by NPC403 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.