AbstractFactory Implementation in ModernC++ Design

Discussion in 'C++' started by Jan, Feb 16, 2011.

  1. Jan

    Jan Guest

    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
    Jan, Feb 16, 2011
    #1
    1. Advertising

  2. Jan

    Jan Guest

    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
    Jan, Feb 16, 2011
    #2
    1. Advertising

  3. On 16 fév, 11:25, Jan <> wrote:
    > 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.

    --
    Michael
    Michael Doubez, Feb 16, 2011
    #3
  4. Jan

    Gil Guest

    On Feb 16, 5:25 am, Jan <> wrote:
    > 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
    Gil, Feb 16, 2011
    #4
  5. Jan

    Jan Guest

    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
    Jan, Feb 17, 2011
    #5
  6. Jan

    Jan Guest

    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
    Jan, Feb 17, 2011
    #6
  7. Jan

    Gil Guest

    On Feb 16, 10:52 pm, Jan <> wrote:
    > 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< ... >::Create< ... > hides (all)
    virtual functions AbstractProductCreator< ....
    >::Create(TypeMapping< ... >).


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

    gil
    Gil, Feb 17, 2011
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rami

    NCO design implementation

    Rami, Apr 21, 2004, in forum: VHDL
    Replies:
    1
    Views:
    2,750
    Jonathan Bromley
    Apr 21, 2004
  2. Amir  Michail
    Replies:
    0
    Views:
    274
    Amir Michail
    Feb 22, 2005
  3. Michael Tsang
    Replies:
    32
    Views:
    1,068
    Richard Bos
    Mar 1, 2010
  4. Michael Tsang
    Replies:
    54
    Views:
    1,152
    Phil Carmody
    Mar 30, 2010
  5. sanket
    Replies:
    7
    Views:
    977
    Tsung
    Nov 3, 2011
Loading...

Share This Page