473,503 Members | 6,354 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Use of class factory in a recursive container

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 constructors) which have this base
class:

template<class T>
class Factory_Base {
public:
virtual ~Factory() {} // (could be pure virtual)
virtual T* create(int n) {return new T[n];} // (could be pure virtual)
};

I also have a container class, Array<T>, which has a constructor that
takes a factory as a parameter:

template<class T>
Array<T>::Array(Factory_Base<T> &f)
{
factory = &f; // Array<T> has a member Factory<T> *factory
}

This works fine as long as I only want to do this:

My_Factory my_factory; // My_Factory creates My_T instances
Array<My_T> my_variable(my_factory);

However, sometimes I want to write like this:

My_Factory my_factory; // My_Factory still creates My_T instances
Array<Array<My_T> > my_variable(my_factory);

The most straightforward solution would be to create a factory that can
create Array<My_T>, but I don't want to do that.

Please tell me that there is another way!

/ Johan
Jul 22 '05 #1
6 2034
Hi,

I made a few typos in my first post so here it all comes again (corrected).

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 constructors) which have this base
class:

template<class T>
class Factory_Base {
public:
virtual ~Factory_Base() {} // (could be pure virtual)
virtual T* create(int n) {return new T[n];} // (could be pure virtual)
};

I also have a container class, Array<T>, which has a constructor that
takes a factory as a parameter:

template<class T>
Array<T>::Array(Factory_Base<T> &f)
{
factory = &f; // Array<T> has a member Factory_Base<T> *factory
}

This works fine as long as I only want to do this:

My_Factory my_factory; // My_Factory creates My_T instances
Array<My_T> my_variable(my_factory);

However, sometimes I want to write like this:

My_Factory my_factory; // My_Factory still creates My_T instances
Array<Array<My_T> > my_variable(my_factory);

The most straightforward solution would be to create a factory that can
create Array<My_T>, but I don't want to do that.

Please tell me that there is another way!

/ Johan
Jul 22 '05 #2
"Johan Bergman" <us**@inter.net> wrote...
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 constructors) which have this base
class:

template<class T>
class Factory_Base {
public:
virtual ~Factory_Base() {} // (could be pure virtual)
virtual T* create(int n) {return new T[n];} // (could be pure virtual)
};

I also have a container class, Array<T>, which has a constructor that
takes a factory as a parameter:

template<class T>
Array<T>::Array(Factory_Base<T> &f)
{
factory = &f; // Array<T> has a member Factory_Base<T> *factory
}

This works fine as long as I only want to do this:

My_Factory my_factory; // My_Factory creates My_T instances
Array<My_T> my_variable(my_factory);

However, sometimes I want to write like this:

My_Factory my_factory; // My_Factory still creates My_T instances
Array<Array<My_T> > my_variable(my_factory);

The most straightforward solution would be to create a factory that can
create Array<My_T>, but I don't want to do that.

Please tell me that there is another way!


You haven't shown how 'Array<>' uses the factory. For all we know,
the way it uses it should allow for "de-Array-fication". You could
write some kind of recursive template to "de-Array-fy" the template
argument until it reaches non-Array-derived type.

template<class T> class Array;

template<class T> class NonArray {
typedef T original;
};

// specialisation for 'Array<T>'
template<class T> class NonArray<Array<T> > {
typedef NonArray<T>::original original; // recursive
};

template<class T> class Array {
typedef Factory_Base< NonArray<T>::original > Real_Factory;
// use Real_Factory somehow
};

This is just a quick sketch, a nugde so to speak. Perhaps you can
dig something useful from it...

Victor
Jul 22 '05 #3
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ywhNb.66727$xy6.124703@attbi_s02...
"Johan Bergman" <us**@inter.net> wrote...
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 constructors) which have this base class:

template<class T>
class Factory_Base {
public:
virtual ~Factory_Base() {} // (could be pure virtual)
virtual T* create(int n) {return new T[n];} // (could be pure virtual) };

I also have a container class, Array<T>, which has a constructor that
takes a factory as a parameter:

template<class T>
Array<T>::Array(Factory_Base<T> &f)
{
factory = &f; // Array<T> has a member Factory_Base<T> *factory
}

This works fine as long as I only want to do this:

My_Factory my_factory; // My_Factory creates My_T instances
Array<My_T> my_variable(my_factory);

However, sometimes I want to write like this:

My_Factory my_factory; // My_Factory still creates My_T instances
Array<Array<My_T> > my_variable(my_factory);

The most straightforward solution would be to create a factory that can
create Array<My_T>, but I don't want to do that.

Please tell me that there is another way!
You haven't shown how 'Array<>' uses the factory.


Oops, you're right! My intention was to let Array<> call factory->create()
whenever it is supposed to create new (non-container) elements, i.e. when
the Array<> is initialized or resized.
For all we know,
the way it uses it should allow for "de-Array-fication". You could
write some kind of recursive template to "de-Array-fy" the template
argument until it reaches non-Array-derived type.

template<class T> class Array;

template<class T> class NonArray {
typedef T original;
};

// specialisation for 'Array<T>'
template<class T> class NonArray<Array<T> > {
typedef NonArray<T>::original original; // recursive
};

template<class T> class Array {
typedef Factory_Base< NonArray<T>::original > Real_Factory;
// use Real_Factory somehow
};

This is just a quick sketch, a nudge so to speak. Perhaps you can
dig something useful from it...


Yes, I think this helps a lot, thanks! (Perhaps you can recommend some good
books where I can learn more about this kind of C++ idioms?)

But now I have another problem. The Array<T> method that creates new
(container or non-container) elements should look something like this:

if (factory == 0)
// No factory was specified by the user
data = new T[n]; // line 3
else if (typeid(T) == typeid(Original))
// Time to use Real_Factory
data = factory->instantiate(n);
else
// T must be an Array of something
data = new T[n](*factory); // line 9

The library I am working on contains some Array<T> instantiations for types
T that don't have constructors that take a factory as a parameter. This
means that the compiler won't accept line 9 (although this line will never
be executed for such types because they will in practice be taken care of by
line 3). Is there any legal way to do this?

/ Johan
Jul 22 '05 #4
I made a typo again. In the post I just made I wrote create() in one place
an instantiate() in another place, but I meant the same function. Below you
will find a corrected version of the post.

/ Johan

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ywhNb.66727$xy6.124703@attbi_s02...
"Johan Bergman" <us**@inter.net> wrote...
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 constructors) which have this base class:

template<class T>
class Factory_Base {
public:
virtual ~Factory_Base() {} // (could be pure virtual)
virtual T* create(int n) {return new T[n];} // (could be pure virtual) };

I also have a container class, Array<T>, which has a constructor that
takes a factory as a parameter:

template<class T>
Array<T>::Array(Factory_Base<T> &f)
{
factory = &f; // Array<T> has a member Factory_Base<T> *factory
}

This works fine as long as I only want to do this:

My_Factory my_factory; // My_Factory creates My_T instances
Array<My_T> my_variable(my_factory);

However, sometimes I want to write like this:

My_Factory my_factory; // My_Factory still creates My_T instances
Array<Array<My_T> > my_variable(my_factory);

The most straightforward solution would be to create a factory that can
create Array<My_T>, but I don't want to do that.

Please tell me that there is another way!
You haven't shown how 'Array<>' uses the factory.


Oops, you're right! My intention was to let Array<> call factory->create()
whenever it is supposed to create new (non-container) elements, i.e. when
the Array<> is initialized or resized.
For all we know,
the way it uses it should allow for "de-Array-fication". You could
write some kind of recursive template to "de-Array-fy" the template
argument until it reaches non-Array-derived type.

template<class T> class Array;

template<class T> class NonArray {
typedef T original;
};

// specialisation for 'Array<T>'
template<class T> class NonArray<Array<T> > {
typedef NonArray<T>::original original; // recursive
};

template<class T> class Array {
typedef Factory_Base< NonArray<T>::original > Real_Factory;
// use Real_Factory somehow
};

This is just a quick sketch, a nudge so to speak. Perhaps you can
dig something useful from it...


Yes, I think this helps a lot, thanks! (Perhaps you can recommend some good
books where I can learn more about this kind of C++ idioms?)

But now I have another problem. The Array<T> method that creates new
(container or non-container) elements should look something like this:

if (factory == 0)
// No factory was specified by the user
data = new T[n]; // line 3
else if (typeid(T) == typeid(Original))
// Time to use Real_Factory
data = factory->create(n);
else
// T must be an Array of something
data = new T[n](*factory); // line 9

The library I am working on contains some Array<T> instantiations for types
T that don't have constructors that take a factory as a parameter. This
means that the compiler won't accept line 9 (although this line will never
be executed for such types because they will in practice be taken care of by
line 3). Is there any legal way to do this?

/ Johan
Jul 22 '05 #5
"Johan Bergman" <us**@inter.net> wrote...
I made a typo again. In the post I just made I wrote create() in one place
an instantiate() in another place, but I meant the same function. Below you will find a corrected version of the post.

/ Johan

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ywhNb.66727$xy6.124703@attbi_s02...
"Johan Bergman" <us**@inter.net> wrote...
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 constructors) which have this base class:

template<class T>
class Factory_Base {
public:
virtual ~Factory_Base() {} // (could be pure virtual)
virtual T* create(int n) {return new T[n];} // (could be pure virtual) };

I also have a container class, Array<T>, which has a constructor that
takes a factory as a parameter:

template<class T>
Array<T>::Array(Factory_Base<T> &f)
{
factory = &f; // Array<T> has a member Factory_Base<T> *factory
}

This works fine as long as I only want to do this:

My_Factory my_factory; // My_Factory creates My_T instances
Array<My_T> my_variable(my_factory);

However, sometimes I want to write like this:

My_Factory my_factory; // My_Factory still creates My_T instances
Array<Array<My_T> > my_variable(my_factory);

The most straightforward solution would be to create a factory that can create Array<My_T>, but I don't want to do that.

Please tell me that there is another way!
You haven't shown how 'Array<>' uses the factory.


Oops, you're right! My intention was to let Array<> call factory->create()
whenever it is supposed to create new (non-container) elements, i.e. when
the Array<> is initialized or resized.
For all we know,
the way it uses it should allow for "de-Array-fication". You could
write some kind of recursive template to "de-Array-fy" the template
argument until it reaches non-Array-derived type.

template<class T> class Array;

template<class T> class NonArray {
typedef T original;
};

// specialisation for 'Array<T>'
template<class T> class NonArray<Array<T> > {
typedef NonArray<T>::original original; // recursive
};

template<class T> class Array {
typedef Factory_Base< NonArray<T>::original > Real_Factory;
// use Real_Factory somehow
};

This is just a quick sketch, a nudge so to speak. Perhaps you can
dig something useful from it...


Yes, I think this helps a lot, thanks! (Perhaps you can recommend some

good books where I can learn more about this kind of C++ idioms?)
I recommend both "Modern C++ Design" by Alexandrescu and "C++ Templates"
by Vandevoorde and Josuttis. Very good books. Try the reverse order,
though. MC++D can be a bit too much.

Also, see Boost library for tons of template tricks. And monitor this
newsgroup. I've seen many interesting posts on templates.
But now I have another problem. The Array<T> method that creates new
(container or non-container) elements should look something like this:

if (factory == 0)
// No factory was specified by the user
data = new T[n]; // line 3
else if (typeid(T) == typeid(Original))
// Time to use Real_Factory
data = factory->create(n);
else
// T must be an Array of something
data = new T[n](*factory); // line 9

The library I am working on contains some Array<T> instantiations for types T that don't have constructors that take a factory as a parameter. This
means that the compiler won't accept line 9 (although this line will never
be executed for such types because they will in practice be taken care of by line 3). Is there any legal way to do this?


I don't know. My ability to write template code is still far from
advanced. I would probably try to specialise the 'create' function
based on 'T', which suggest that it should be a member template...

Victor
Jul 22 '05 #6
Thanks, your answers helped me a lot!

BR,
Johan

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:3PFNb.77410$na.42900@attbi_s04...
"Johan Bergman" <us**@inter.net> wrote...
I made a typo again. In the post I just made I wrote create() in one place
an instantiate() in another place, but I meant the same function. Below you
will find a corrected version of the post.

/ Johan

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ywhNb.66727$xy6.124703@attbi_s02...
"Johan Bergman" <us**@inter.net> wrote...
> 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 constructors) which have this

base
> class:
>
> template<class T>
> class Factory_Base {
> public:
> virtual ~Factory_Base() {} // (could be pure virtual)
> virtual T* create(int n) {return new T[n];} // (could be pure

virtual)
> };
>
> I also have a container class, Array<T>, which has a constructor that > takes a factory as a parameter:
>
> template<class T>
> Array<T>::Array(Factory_Base<T> &f)
> {
> factory = &f; // Array<T> has a member Factory_Base<T> *factory
> }
>
> This works fine as long as I only want to do this:
>
> My_Factory my_factory; // My_Factory creates My_T instances
> Array<My_T> my_variable(my_factory);
>
> However, sometimes I want to write like this:
>
> My_Factory my_factory; // My_Factory still creates My_T instances
> Array<Array<My_T> > my_variable(my_factory);
>
> The most straightforward solution would be to create a factory that can > create Array<My_T>, but I don't want to do that.
>
> Please tell me that there is another way!

You haven't shown how 'Array<>' uses the factory.


Oops, you're right! My intention was to let Array<> call

factory->create() whenever it is supposed to create new (non-container) elements, i.e. when the Array<> is initialized or resized.
For all we know,
the way it uses it should allow for "de-Array-fication". You could
write some kind of recursive template to "de-Array-fy" the template
argument until it reaches non-Array-derived type.

template<class T> class Array;

template<class T> class NonArray {
typedef T original;
};

// specialisation for 'Array<T>'
template<class T> class NonArray<Array<T> > {
typedef NonArray<T>::original original; // recursive
};

template<class T> class Array {
typedef Factory_Base< NonArray<T>::original > Real_Factory;
// use Real_Factory somehow
};

This is just a quick sketch, a nudge so to speak. Perhaps you can
dig something useful from it...


Yes, I think this helps a lot, thanks! (Perhaps you can recommend some

good
books where I can learn more about this kind of C++ idioms?)


I recommend both "Modern C++ Design" by Alexandrescu and "C++ Templates"
by Vandevoorde and Josuttis. Very good books. Try the reverse order,
though. MC++D can be a bit too much.

Also, see Boost library for tons of template tricks. And monitor this
newsgroup. I've seen many interesting posts on templates.
But now I have another problem. The Array<T> method that creates new
(container or non-container) elements should look something like this:

if (factory == 0)
// No factory was specified by the user
data = new T[n]; // line 3
else if (typeid(T) == typeid(Original))
// Time to use Real_Factory
data = factory->create(n);
else
// T must be an Array of something
data = new T[n](*factory); // line 9

The library I am working on contains some Array<T> instantiations for

types
T that don't have constructors that take a factory as a parameter. This
means that the compiler won't accept line 9 (although this line will never be executed for such types because they will in practice be taken care

of by
line 3). Is there any legal way to do this?


I don't know. My ability to write template code is still far from
advanced. I would probably try to specialise the 'create' function
based on 'T', which suggest that it should be a member template...

Victor

Jul 22 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
4799
by: MPowell | last post by:
I'm going through the Koeing book Accelerated C++ in an attempt to understand Container classes. Of course I'm going through a paradigm shift from C to C++. So now I've got struct Header {...
1
1513
by: Ronald Landheer-Cieslak | last post by:
Hello all, We're coding a really nice implementation of a generic abstract factory at the moment, but we've come to a slight impass we have to work around: when automagically registering a class...
1
2372
by: Jon Slaughter | last post by:
I've managed to put together a template class that basicaly creates a recursive tree that lets you easily specify the "base" class of that tree and and ending notes and lets you stop the recursive...
10
2101
by: PengYu.UT | last post by:
Hi, Maybe this is an simple question. How can I insure that the objects of a class must be allocated in the heap? Thanks, Peng
9
1342
by: lou zion | last post by:
hey all, i've got a class that A that has a static class member static int MajorMode; it's important that if one instance of the class changes this variable, all instances react...
11
1805
by: Manuel | last post by:
Hi, I need implement a map of member functions of some class. This map is formed by a string and a pointer to the member function. The problem is that the map need that the object saved are...
6
1913
by: rep_movsd | last post by:
Hi folks I was on topcoder and came across an interesting problem... It involved dynamic programming ( storing function results in a map to avoid repeated computation ) and I ended up having...
15
3503
by: Juha Nieminen | last post by:
I'm sure this is not a new idea, but I have never heard about it before. I'm wondering if this could work: Assume that you have a common base class and a bunch of classes derived from it, and...
4
2360
by: Bit Byter | last post by:
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...
0
7291
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7012
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7468
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5598
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3180
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3171
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1522
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
748
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
402
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.