Implementing Adapter Pattern with class and method renaming

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Maurice

    Implementing Adapter Pattern with class and method renaming

    Hi,

    We are implementing some wrappers in C++ according to the Adapter
    Pattern. The classes and their methods in the Adaptee classes
    (open-source library) have already the interface that we like, but we
    want to rename them so we want to implement the Adapter classes in
    such a way that we only have to rename the Adaptee classes. We prefer
    to use #define's because of the better run-time performance, in stead
    of implementing wrapper functions.

    In our case we have an Adaptee class that looks like this (simplified
    example):

    class Adaptee
    {
    public:
    int Method1(int in);
    int Method2(void);
    private:
    int Attribute;
    };

    This Adaptee class is implemented and build in a library.

    Now we create an Adapter class (derived from a (abstract) Target
    class) that is defined in the .h-file and looks like this (simplified
    example):

    class Adapter : public Target
    {
    public:
    int my_method_1(int in);
    int my_method_2(voi d);
    };

    In the corresponing .cpp-file we include this .h-file and implement
    the Adapter class in the following way:

    #define Adapter Adaptee
    #define my_method_1 Method1
    #define my_method_2 Method2

    If we build our Adapter and Target classes into a library, everything
    goes fine. There are no compile or link errors.

    Now we use our self-created library in an application, but then we got
    linking errors to tell us that we have: "unresolved external symbols"
    on the methods that are part of the Adapter classes. Our application
    looks like this (simplified example):

    int main(int argc, char *argv[])
    {
    int Result;
    Adapter MyAdapter;
    Target *pMyTarget = &MyAdapter;

    Result = pMyTarget->my_method_1(0) ;
    Result = pMyTarget->my_method_2( );

    return Result;
    }

    So my question is now. Can someone explain me what we are doing wrong
    and how we can solve these linking errors?

    Thanks,
    Maurice
  • tom_usenet

    #2
    Re: Implementing Adapter Pattern with class and method renaming

    On 3 Oct 2003 06:34:51 -0700, maurice.heffels @ict.nl (Maurice) wrote:
    [color=blue]
    >Hi,
    >
    >We are implementing some wrappers in C++ according to the Adapter
    >Pattern. The classes and their methods in the Adaptee classes
    >(open-source library) have already the interface that we like, but we
    >want to rename them so we want to implement the Adapter classes in
    >such a way that we only have to rename the Adaptee classes. We prefer
    >to use #define's because of the better run-time performance, in stead
    >of implementing wrapper functions.[/color]

    Inlined wrapper functions shouldn't suffer a performance hit -
    performance should be indentical to the #define approach (and it will
    actually work, unlike the #define approach).
    [color=blue]
    >
    >In our case we have an Adaptee class that looks like this (simplified
    >example):
    >
    > class Adaptee
    > {
    > public:
    > int Method1(int in);
    > int Method2(void);
    > private:
    > int Attribute;
    > };
    >
    >This Adaptee class is implemented and build in a library.
    >
    >Now we create an Adapter class (derived from a (abstract) Target
    >class) that is defined in the .h-file and looks like this (simplified
    >example):
    >
    > class Adapter : public Target
    > {
    > public:
    > int my_method_1(int in);
    > int my_method_2(voi d);
    > };[/color]

    Ok so far. You've got a library (and header) for Adaptee, and you've
    created a header for your own class Adapter, derived from Target.
    [color=blue]
    >In the corresponing .cpp-file we include this .h-file and implement
    >the Adapter class in the following way:
    >
    > #define Adapter Adaptee
    > #define my_method_1 Method1
    > #define my_method_2 Method2[/color]

    Where are the defines? Before the #includes?

    What you are doing is creating the following class (after
    preprocessing):

    class Adaptee : public Target
    {
    public:
    int Method1(int in);
    int Method2(void);
    };

    [color=blue]
    >If we build our Adapter and Target classes into a library, everything
    >goes fine. There are no compile or link errors.[/color]

    But you never build a class called "Adapter"! You build one called
    Adaptee.
    [color=blue]
    >Now we use our self-created library in an application, but then we got
    >linking errors to tell us that we have: "unresolved external symbols"
    >on the methods that are part of the Adapter classes.[/color]

    I'm not surprised, since you haven't compiled the methods of a class
    called Adapter.

    Our application[color=blue]
    >looks like this (simplified example):
    >
    > int main(int argc, char *argv[])
    > {
    > int Result;
    > Adapter MyAdapter;
    > Target *pMyTarget = &MyAdapter;
    >
    > Result = pMyTarget->my_method_1(0) ;
    > Result = pMyTarget->my_method_2( );
    >
    > return Result;
    > }
    >
    >So my question is now. Can someone explain me what we are doing wrong
    >and how we can solve these linking errors?[/color]

    Well, I've said what's wrong. To fix it you have two options.
    1. Modify the source of Adaptee.cpp to this:

    was something like:
    #include "Adaptee.h"
    //member definitions.

    change it to something like:
    #include "Adaptor.h" //your header!

    #define Adaptee Adapter
    #define Method1 my_method_1
    #define Method2 my_method_2
    //member definitions unmodified

    and recompile Adaptee.cpp into its library, where it will actually be
    linked in as Adaptor.


    Or, much better, you can to do things properly:

    #include "Target.h"
    #include "Adaptee.h" //from library

    class Adapter : public Target, private Adaptee
    {
    public:
    int my_method_1(int in)
    {
    return Method1(in);
    }
    int my_method_2(voi d)
    {
    return Method2();
    }
    };

    Because the functions are defined inline in the class, you shouldn't
    get any performance hit.

    Tom

    Comment

    Working...