Boost logo

Boost :

Subject: Re: [boost] [interfaces] Boost Interface Library (2004?)
From: Daniel Larimer (dlarimer_at_[hidden])
Date: 2011-02-06 23:21:42


On Feb 6, 2011, at 9:27 PM, Edward Diener wrote:

> On 2/6/2011 8:01 PM, Daniel Larimer wrote:
>>
>> On Feb 6, 2011, at 5:58 PM, Edward Diener wrote:
>>
>>> On 2/6/2011 4:18 PM, Joaquin M Lopez Munoz wrote:
>>>> Edward Diener<eldiener<at> tropicsoft.com> writes:
>>>>
>>>>>
>>>>> On 2/6/2011 3:07 PM, Daniel Larimer wrote:
>>>>>> I recently ran across the unofficial Boost Interface Library
>>>>>> (http://www.coderage.com/interfaces),
>>>>>
>>>>> How are is an interface any different than a C++ abstract class ?
>>>>
>>>> As the concept is defined by the aforementioned library,
>>>> interfaces allow for dynamic duck typing.
>>>
>>> It is not your problem but I did not get much of an understanding from the OP's original description of what advantages his implementation has over using C++ abstract classes to define interfaces. In other words what duck typing has to offer in terms of use which makes it better.
>>
>> It is not always possible to change the inheritance hierarchy of other types that you want to use in a polymorphic way. Sometimes you need to add a polymorphic interface to a class that you do not want a vtable for. Every method in an abstract class becomes a virtual dispatch even when most use cases do not require or cannot benefit from virtual dispatching.
>
> So you want the effective of an abstract class without the virtual methods ?
>
>>
>> All of those reasons aside, my interest in the subject is because I want to dynamically create stubs for RPC, scripting, etc and there is no way to do that via an abstract class.
>
> There is nothing on the C++ standard about RPC stubs so when you say that there is no way to do that from an abstract class you must be referring to some 3rd party library you are using.

        You can create an abstract class, but it requires code generation or manually coding the RPC stub that inherits from the abstract class. I have a strong dislike for anything that requires code generation because it is fragile and introduces extra complexity to your build process.

>
> I have dealt with RPC in a project I once worked on for Hewlett-Packard but I admit I no longer remember how the IDL was created, or even if it was done manually or programatically.
>
> In any case I encourage you to explain the use case(s) of your library as carefully as you can in order to get others interested in it.

Suppose you had a calculator class that you want to expose as an RPC service:

struct calculator
{
        virtual int add( int, int ) = 0;
};

You could implement an abstract base class and then implement 3 other classes (calculator_impl, calculator_client, calculator_server) such that your code is set up like so:

struct calculator_impl : calculator
{
        int add( int a, int b ) { return a + b; }
};
struct calcualtor_client : calculator
{
        int add( int a, int b ) {
                udp_socket->send( pack(a,b), server_endpoint );
                return unpack_int( udp_sock->recv() );
        }
};
struct calcualtor_server
{
        void udp_recv( packet ) { int sum = calc->add( unpack(packet) ); } udp_send(pack(sum)); }
        calculator_impl* calc;
};

Any time you change your calculator interface you must now modify code in 4 places. It becomes a mess to maintain.

Now lets take a closer look at calculator_client. Ideally you would like the client interface to be:

struct calculator_client
{
        future<int> add( int, int );
}

Or suppose you and a more advanced protocol that supports different calling conventions (no return, scheduling, guarantees, retransmit attempts, etc). Now you
want an interface like:

struct calculator_client
{
        struct add_
        {
                future<int> operator(int,int);
                void invoke_without_return(int,int);
        }add;
};

There is a well defined transformation between the abstract interface and the interface for the client and server.

Now suppose you want to write some code that can deal with either calculator_client or calculator*. You are up a creak because there is no way to create an abstract base class for calculator_client and calculator because the calculator_client is implemented with function object member variables.

So the goal and purpose of the IDL library is to describe an interface in such a way that it is easy to provide dynamic implementations/transformations of that interface and then deal with them all in a polymorphic manner.

>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk