Mixing interface and functional inheritance

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

    Mixing interface and functional inheritance

    Below is a code snippet that fails to compile under vc.net

    class BaseInterface
    {
    public:
    virtual void f() = 0;
    };

    class BaseImplementat ion : public BaseInterface
    {
    public:
    void f(){}
    };

    class ExtraInterface : public BaseInterface
    {
    virtual void g() = 0;
    };

    class ExtraImplementa tion: public BaseImplementat ion, public
    ExtraInterface
    {
    void g(){}
    };

    void func()
    {
    ExtraImplementa tion d;
    }

    The compiler complains that ExtraImplementa tion is an abstract class
    and therefore cannot be initialized. Function f, despite being
    defined in BaseImplementat ion, is undefined in ExtraImplementa tion.

    I hope it's clear what I'm trying to do, i.e., maintaining two
    inheritance lines that parallel each other. One line consists of
    interfaces and the other implementation. Am I misguided in my
    efforts?

    Kevin
  • Alf P. Steinbach

    #2
    Re: Mixing interface and functional inheritance

    On 22 Sep 2003 17:39:26 -0700, inkdust@hotmail .com (Kevin L) wrote:
    [color=blue]
    >Below is a code snippet that fails to compile under vc.net
    >
    >class BaseInterface
    >{
    >public:
    > virtual void f() = 0;
    >};
    >
    >class BaseImplementat ion : public BaseInterface
    >{
    >public:
    > void f(){}
    >};
    >
    >class ExtraInterface : public BaseInterface
    >{[/color]

    -- public:

    [color=blue]
    > virtual void g() = 0;
    >};
    >
    >class ExtraImplementa tion: public BaseImplementat ion, public
    >ExtraInterfa ce
    >{[/color]

    -- public:

    [color=blue]
    > void g(){}
    >};
    >
    >void func()
    >{
    > ExtraImplementa tion d;
    >}
    >
    >The compiler complains that ExtraImplementa tion is an abstract class
    >and therefore cannot be initialized. Function f, despite being
    >defined in BaseImplementat ion, is undefined in ExtraImplementa tion.[/color]

    The compiler is correct.

    In Java you can inherit a function spec from an interface, and an
    implementation of that function from a concrete class. In C++ the
    two inheritance chains are distinct, functions in one don't map
    onto functions in the other, unless you use virtual inheritance,
    which is both messy and a tad inefficient.

    Instead of using virtual inheritance (the tech level solution) I
    recommend _factoring out_ the ExtraInterface, like this:


    class ExtraInterface
    {
    public:
    virtual void g() = 0;
    };


    Now isn't that nice?

    [color=blue]
    >I hope it's clear what I'm trying to do, i.e., maintaining two
    >inheritance lines that parallel each other. One line consists of
    >interfaces and the other implementation.[/color]

    You can do that as shown above.

    I do not recommend the virtual inheritance alternative.


    [color=blue]
    >Am I misguided in my efforts?[/color]

    Not enough information to say, but probably not; however, it seems
    you come from a Java or perhaps C# background, and need to ditch
    much of the low-level details from the previous language, while
    holding on the high-level concepts (which you'll have to _implement_,
    some times by adhering strictly to some convention, in C++).

    Comment

    • Gianni Mariani

      #3
      Re: Mixing interface and functional inheritance

      Kevin L wrote:[color=blue]
      > Below is a code snippet that fails to compile under vc.net
      >
      > class BaseInterface
      > {
      > public:
      > virtual void f() = 0;
      > };
      >
      > class BaseImplementat ion : public BaseInterface
      > {
      > public:
      > void f(){}
      > };
      >
      > class ExtraInterface : public BaseInterface
      > {
      > virtual void g() = 0;
      > };
      >
      > class ExtraImplementa tion: public BaseImplementat ion, public
      > ExtraInterface
      > {
      > void g(){}
      > };
      >
      > void func()
      > {
      > ExtraImplementa tion d;
      > }
      >
      > The compiler complains that ExtraImplementa tion is an abstract class
      > and therefore cannot be initialized. Function f, despite being
      > defined in BaseImplementat ion, is undefined in ExtraImplementa tion.
      >
      > I hope it's clear what I'm trying to do, i.e., maintaining two
      > inheritance lines that parallel each other. One line consists of
      > interfaces and the other implementation. Am I misguided in my
      > efforts?[/color]

      The virtual inheritance mechanism is what is intended to solve the problem.

      class BaseInterface
      {
      public:
      virtual void f() = 0;
      };

      class BaseImplementat ion : public *virtual* BaseInterface
      {
      public:
      void f(){}
      };

      class ExtraInterface : public *virtual* BaseInterface
      {
      virtual void g() = 0;
      };

      class ExtraImplementa tion: public BaseImplementat ion, public
      ExtraInterface
      {
      void g(){}
      };

      void func()
      {
      ExtraImplementa tion d;
      }

      Comment

      • Kevin L

        #4
        Re: Mixing interface and functional inheritance

        alfps@start.no (Alf P. Steinbach) wrote in message news:<3f6f98aa. 907775187@News. CIS.DFN.DE>...[color=blue]
        > On 22 Sep 2003 17:39:26 -0700, inkdust@hotmail .com (Kevin L) wrote:
        >[color=green]
        > >Below is a code snippet that fails to compile under vc.net
        > >
        > >class BaseInterface
        > >{
        > >public:
        > > virtual void f() = 0;
        > >};
        > >
        > >class BaseImplementat ion : public BaseInterface
        > >{
        > >public:
        > > void f(){}
        > >};
        > >
        > >class ExtraInterface : public BaseInterface
        > >{[/color]
        >
        > -- public:
        >
        >[color=green]
        > > virtual void g() = 0;
        > >};
        > >
        > >class ExtraImplementa tion: public BaseImplementat ion, public
        > >ExtraInterfa ce
        > >{[/color]
        >
        > -- public:
        >
        >[color=green]
        > > void g(){}
        > >};
        > >
        > >void func()
        > >{
        > > ExtraImplementa tion d;
        > >}
        > >[/color][/color]
        ....[color=blue]
        >
        > Instead of using virtual inheritance (the tech level solution) I
        > recommend _factoring out_ the ExtraInterface, like this:
        >
        >
        > class ExtraInterface
        > {
        > public:
        > virtual void g() = 0;
        > };
        >
        >[/color]
        ....
        Ah, but now I can't pass an object of ExtraImplementa tion as
        ExtraInterface and have the BaseInterface functions available without
        casting.

        Now if I stick to strict abstract classes for the interfaces (no data
        members), I can sidestep much of the messiness involved in virtual
        inheritance, correct? The inheritance tree I am building is meant for
        exception classes. I expect them to be constructed and used quite
        infrequently. Right now I'm leaning toward the virtual inheritance
        solution. Any reason not to?

        Thanks for the reply.

        Kevin

        Comment

        • Alf P. Steinbach

          #5
          Re: Mixing interface and functional inheritance

          On 23 Sep 2003 00:58:28 -0700, inkdust@hotmail .com (Kevin L) wrote:
          [color=blue]
          >alfps@start. no (Alf P. Steinbach) wrote in message news:<3f6f98aa. 907775187@News. CIS.DFN.DE>...[color=green]
          >> On 22 Sep 2003 17:39:26 -0700, inkdust@hotmail .com (Kevin L) wrote:
          >>[color=darkred]
          >> >Below is a code snippet that fails to compile under vc.net
          >> >
          >> >class BaseInterface
          >> >{
          >> >public:
          >> > virtual void f() = 0;
          >> >};
          >> >
          >> >class BaseImplementat ion : public BaseInterface
          >> >{
          >> >public:
          >> > void f(){}
          >> >};
          >> >
          >> >class ExtraInterface : public BaseInterface
          >> >{[/color]
          >>
          >> -- public:
          >>
          >>[color=darkred]
          >> > virtual void g() = 0;
          >> >};
          >> >
          >> >class ExtraImplementa tion: public BaseImplementat ion, public
          >> >ExtraInterfa ce
          >> >{[/color]
          >>
          >> -- public:
          >>
          >>[color=darkred]
          >> > void g(){}
          >> >};
          >> >
          >> >void func()
          >> >{
          >> > ExtraImplementa tion d;
          >> >}
          >> >[/color][/color]
          >...[color=green]
          >>
          >> Instead of using virtual inheritance (the tech level solution) I
          >> recommend _factoring out_ the ExtraInterface, like this:
          >>
          >>
          >> class ExtraInterface
          >> {
          >> public:
          >> virtual void g() = 0;
          >> };
          >>
          >>[/color]
          >...
          >Ah, but now I can't pass an object of ExtraImplementa tion as
          >ExtraInterfa ce and have the BaseInterface functions available without
          >casting.[/color]

          First, you _can_ hardwire the relationship, via an accessor method
          in ExtraInterface.

          But, second, why would you want to do that?


          [color=blue]
          >Now if I stick to strict abstract classes for the interfaces (no data
          >members), I can sidestep much of the messiness involved in virtual
          >inheritance, correct? The inheritance tree I am building is meant for
          >exception classes. I expect them to be constructed and used quite
          >infrequently . Right now I'm leaning toward the virtual inheritance
          >solution. Any reason not to?[/color]

          1 In the most derived class you may have to call the constructor of
          the root class.

          2 Virtual inheritance mixed with non-virtual inheritance is very
          messy. You're in for a maintainance nightmare.

          3 It's a tad inefficient, also.

          Comment

          Working...