472,992 Members | 3,808 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,992 software developers and data experts.

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 2330


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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Simon Elliott | last post by:
I have a class which uses a singleton to output progress messages for logging or display. It's typically used deep within a hierarchy of aggregations, inheritances and containers. The singleton...
5
by: Thomas Matthews | last post by:
Hi, I have a Display class. I would like to write a function that takes a range of objects and displays them. The range would be specified by two forward iterators: start and end (one past...
6
by: Johan Bergman | last post by:
Hi, Maybe someone can help me with this one. The following describes a somewhat simplified version of my problem, but I think it will be sufficient. I want to use class factories (virtual...
9
by: Jon Wilson | last post by:
I have a class which needs to accumulate data. The way we get this data is by calling a member function which returns float on a number of different objects of different type (they are all the...
21
by: Jon Slaughter | last post by:
I have a class that is basicaly duplicated throughout several files with only members names changing according to the class name yet with virtually the exact same coding going on. e.g. class...
3
by: KK | last post by:
Hello all, I have several classes binded by one common interface - say 'sum' interface which calculates the sum of all the class elements of type 'int'. class Alphabet { int _a; int _b; int...
7
by: ankitjain.bvcoe | last post by:
Hi i have the following problem in my design :::: i want to define an abstract class LogBuffer and derive two singleton classes from it i.e AlarmBuffer and FireWallBuffer.For this my design is...
12
by: keepyourstupidspam | last post by:
Hi, I am writing a windows service. The code runs fine when I start the service when my machine is running but it fails to start automatically when the machine reboots. The code bombs out when...
2
by: Eric Lilja | last post by:
As the topic says, I wanted to make a re-usable singleton class that could create pointers to objects with non-trivial constructors. I came up with this: #ifndef SINGLETON_HPP #define...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...
3
SueHopson
by: SueHopson | last post by:
Hi All, I'm trying to create a single code (run off a button that calls the Private Sub) for our parts list report that will allow the user to filter by either/both PartVendor and PartType. On...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.