AbstractFactory Implementation in ModernC++ Design

J

Jan

Hi Folks,

I was reading Andrei Alexandrescu's Modern C++ Design and I decided to
get my hands dirty with the code.

I tried implementing parts of his code and tried to put up a simple
AbstractFactory.

I ran into some compile issues.

My main.cpp is here http://codepad.org/cGsBF3Ba
My AbstractFactoryClass header file is here http://codepad.org/Z4iQnOGQ
My TypesCollection header file is here http://codepad.org/SEDgJF14

I get the following error when I try to compile this code:

main.cpp: In function 'main':
main.cpp:59: error: expected primary-expression before '>' token
main.cpp:49: error: expected primary-expression before ')' token
main.cpp:50: error: expected primary-expression before '>' token
main.cpp:50: error: expected primary-expression before ')' token

I tried fixing this by changing Line 26 in AbstractFactoryClass header
above

from : return unit.Create(TypeMapping<T>());
to : return unit.template Create(TypeMapping<T>());

but that does not fix this error either and I got the same errors
above.

I would be grateful if someone can help me with this error.

On the same note, I would like to add that I get the same error when I
try to use Alexandrescu's Loki library. So maybe my understanding
itself is wrong. Kindly help me learn.

Regards
Janani
 
J

Jan

Hi,

I noticed that #include path in AbstractFactoryClass header above is
not right.

So if you are trying to compile my code above, kindly change it from
#include "applogic/web/Compliance/tools/TypesCollection.h" to #include
TypesCollection.h"

I regret the inconvenience caused.

Regards
Janani
 
M

Michael Doubez

Hi Folks,

I was reading Andrei Alexandrescu's Modern C++ Design and I decided to
get my hands dirty with the code.

I tried implementing parts of his code and tried to put up a simple
AbstractFactory.

I ran into some compile issues.

My main.cpp is herehttp://codepad.org/cGsBF3Ba
My AbstractFactoryClass header file is herehttp://codepad.org/Z4iQnOGQ
My TypesCollection header file is herehttp://codepad.org/SEDgJF14

I get the following error when I try to compile this code:

main.cpp: In function 'main':
main.cpp:59: error: expected primary-expression before '>' token
main.cpp:49: error: expected primary-expression before ')' token
main.cpp:50: error: expected primary-expression before '>' token
main.cpp:50: error: expected primary-expression before ')' token

I tried fixing this by changing Line 26 in AbstractFactoryClass header
above

from : return unit.Create(TypeMapping<T>());
to     : return unit.template Create(TypeMapping<T>());

but that does not fix this error either and I got the same errors
above.

I would be grateful if someone can help me with this error.

The relevant lines should be:
49. Base1* ptr1 = factory.Create<Base1>();
50. Base2* ptr2 = factory.Create<Base2>();

There is no point in abstract factory if you know the real type.
 
G

Gil

Hi Folks,

I was reading Andrei Alexandrescu's Modern C++ Design and I decided to
get my hands dirty with the code.

I tried implementing parts of his code and tried to put up a simple
AbstractFactory.

I ran into some compile issues.

My main.cpp is herehttp://codepad.org/cGsBF3Ba
My AbstractFactoryClass header file is herehttp://codepad.org/Z4iQnOGQ
My TypesCollection header file is herehttp://codepad.org/SEDgJF14

I get the following error when I try to compile this code:

main.cpp: In function 'main':
main.cpp:59: error: expected primary-expression before '>' token
main.cpp:49: error: expected primary-expression before ')' token
main.cpp:50: error: expected primary-expression before '>' token
main.cpp:50: error: expected primary-expression before ')' token

I tried fixing this by changing Line 26 in AbstractFactoryClass header
above

from : return unit.Create(TypeMapping<T>());
to : return unit.template Create(TypeMapping<T>());

but that does not fix this error either and I got the same errors
above.

I would be grateful if someone can help me with this error.

On the same note, I would like to add that I get the same error when I
try to use Alexandrescu's Loki library. So maybe my understanding
itself is wrong. Kindly help me learn.

Regards
Janani

the 3rd template parameter of your AbstractFactoryImpl already defines
the list of concrete products.
that is, it ultimately instatiates things like:

class ProductCreatorUsingNew< Derived1, boiler_plate_type >
: public boiler_plate_type {
//... type list boiler plate
public:
Derived1* Create(TypeMapping<Base1>)
{
return new Derived1;
}
};

so when you do then

Base1* ptr1 = factory.Create<Base1>();

what you actually get is a Derived1 object address, as *intended*.

so you define the abstract products with the abstract factory type (1)
and you define the concrete products when you define factory
implementation type (2):

//I want to create objects derived from Base1, Base2 etc
(1) typedef AbstractFactory<
TYPECOLLECTION_2(Base1, Base2)
> AbstractBaseFactory;

//with their concrete type Derived1, Derived2 etc by using
//this creator ProductCreatorUsingNew
(2) typedef AbstractFactoryImpl<
AbstractBaseFactory,
ProductCreatorUsingNew,
TYPECOLLECTION_2(Derived1, Derived2)
> DerivedFactory1;

additionally, in your scenario, you cannot call

Base1* ptr1 = factory.Create<Derived1>();

because AbstractFactory::Create needs the base (abstract in your
terminology) type to find the right "Unit creator" and dispatch it to
the right Create overloaded method.

I don't have Alexandrescu's book but I looked at loki-lib sources on
sourceforge and I suspect this is a generic implementation of a an
abstract factory pattern.

if so you may want to check a more simple (and reasonable?) approach:
boost::factory/value_factory.

note: you needn't add template prefix on AbstractFactory::Create call,
that method is not a template method.

gil
 
J

Jan

Hi gil and Michael,

Thanks a lot for clearing that up. I have made that change and I also
understood from gil's clear explanation as to why those two lines must
be changed.

But I am still facing the same compiler issue. Changing Derived1 and
Derived2 to Base1 and Base2 does not solve the compiler issue.

Can you help me with this? Any pointers would be greatly appreciated.

Regards
Janani
 
J

Jan

Hi Guys,

Thanks so much for your help.

I was able to get rid of the compiler errors by changing the name of
"Create" function in AbstractFactoryClass to "CreateProduct". I am yet
to figure out why this worked though. The TypeMapping helper class
(equivalent of Type2Type in Modern C++ Design) would help
differentiating between the Create functions in AbstractProductCreator
and also from the original Create function within
AbstractFactoryClass. So the compiler should not have had any trouble
in distinguishing between the functions in the Generated Hierarchy. I
am still not sure why but for now the problem is resolved and
everything works as expected. If I have missed something, I would be
glad to learn.

Thanks a lot for the help guys.

Regards
Janani
 
G

Gil

Hi gil and Michael,

Thanks a lot for clearing that up. I have made that change and I also
understood from gil's clear explanation as to why those two lines must
be changed.

But I am still facing the same compiler issue. Changing Derived1 and
Derived2 to Base1 and Base2 does not solve the compiler issue.

Can you help me with this? Any pointers would be greatly appreciated.

Regards
Janani

if you haven't figured out already why you must change either the
AbstractProductCreator::Create or AbstractFactory::Create to something
else it is because of name hiding:

AbstractFactory said:
::Create(TypeMapping< ... >).

note: you have a case of failed overload resolution because of name
hiding.

gil
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,044
Latest member
RonaldNen

Latest Threads

Top