extending classes and implementing interfaces C++ style

Discussion in 'C++' started by interec@interec.net, Feb 1, 2007.

  1. Guest

    I have some code in Java that I need to translate into C++. My Java
    code defines a class hierarchy as follows:

    // interface IA
    public interface IA
    {
    public abstract void doA();
    }

    // interface IB
    public interface IB extends interface IA
    {
    public abstract void doB();
    }

    // concrete class JA conforming to interface IA
    public class JA implements IA
    {
    public void doA() { ... }
    }

    // concrete class JB extending from JA (so that JB knows about method
    doA() ) and
    // conforms to interface IB (which is derived from interface IA)
    public class JB extends JB implements IB
    {
    public void doB() { ...}
    }

    How do I translate these classes into C++ (specially class JB),
    without duplicating code in C++ equivalent classes of JA and JB and
    while making sure that JA and JB conform to their respecting
    interfaces IA and IB.

    Thanks

    -- Albert
    Webmaster, InterEC.NET
     
    , Feb 1, 2007
    #1
    1. Advertising

  2. Guest

    Here is what I have so far:


    // interface IA
    class IA
    {
    public:
    IA() {}
    virtual ~IA() {}

    void doA() throw() = 0;
    }

    // interface IB
    class IB: public IA
    {
    public:
    IB() {}
    virtual ~IB() {}

    void doB() throw() = 0;
    }

    // concrete class JA conforming to interface IA
    class JA: public IA
    {
    public:
    JA() {}
    virtual ~JA()

    void doA throw() { ... }
    }

    // concrete class JB conforming to interface IB
    class JA: public JA, public IB
    {
    public JB() {}
    virtual ~JB()

    void doB throw() { ... }
    }

    When I compile this, I get an error message saying that doA is
    abstract in class JA????
     
    , Feb 1, 2007
    #2
    1. Advertising

  3. Ondra Holub Guest

    napsal:
    > Here is what I have so far:
    >
    >
    > // interface IA
    > class IA
    > {
    > public:
    > IA() {}
    > virtual ~IA() {}
    >
    > void doA() throw() = 0;
    > }
    >
    > // interface IB
    > class IB: public IA
    > {
    > public:
    > IB() {}
    > virtual ~IB() {}
    >
    > void doB() throw() = 0;
    > }
    >
    > // concrete class JA conforming to interface IA
    > class JA: public IA
    > {
    > public:
    > JA() {}
    > virtual ~JA()
    >
    > void doA throw() { ... }
    > }
    >
    > // concrete class JB conforming to interface IB
    > class JA: public JA, public IB
    > {
    > public JB() {}
    > virtual ~JB()
    >
    > void doB throw() { ... }
    > }
    >
    > When I compile this, I get an error message saying that doA is
    > abstract in class JA????


    class JA: public JA, public IB is nonsense (I think it is typo) -
    class cannot inherit from itself.

    doA is abstract, because it is declared as void doA() throw() = 0;,
    but I miss there key word virtual (in C++ are not all methods virtual
    as in some other languages).
     
    Ondra Holub, Feb 1, 2007
    #3
  4. Alan Johnson Guest

    wrote:
    > I have some code in Java that I need to translate into C++. My Java
    > code defines a class hierarchy as follows:
    >
    > // interface IA
    > public interface IA
    > {
    > public abstract void doA();
    > }
    >
    > // interface IB
    > public interface IB extends interface IA
    > {
    > public abstract void doB();
    > }
    >
    > // concrete class JA conforming to interface IA
    > public class JA implements IA
    > {
    > public void doA() { ... }
    > }
    >
    > // concrete class JB extending from JA (so that JB knows about method
    > doA() ) and
    > // conforms to interface IB (which is derived from interface IA)
    > public class JB extends JB implements IB
    > {
    > public void doB() { ...}
    > }
    >
    > How do I translate these classes into C++ (specially class JB),
    > without duplicating code in C++ equivalent classes of JA and JB and
    > while making sure that JA and JB conform to their respecting
    > interfaces IA and IB.
    >
    > Thanks
    >
    > -- Albert
    > Webmaster, InterEC.NET
    >


    Assuming that last class was supposed to be:
    public class JB extends JA implements IB

    I think this is what you want.

    class IA
    {
    public:
    virtual ~IA() {}
    virtual void doA() = 0 ;
    } ;

    class IB : virtual public IA
    {
    public:
    virtual void doB() = 0 ;
    } ;

    class JA : virtual public IA
    {
    public:
    virtual void doA()
    {
    std::cout << "JA::doA()" << std::endl ;
    }
    } ;

    class JB : public JA, public IB
    {
    public:
    virtual void doB()
    {
    std::cout << "JB::doB()" << std::endl ;
    }
    } ;

    Some notes:
    The virtual keyword is not required everywhere I used it. Once you make
    a function virtual in a base class, it remains virtual in derived
    classes whether you declare it as such or not.

    The "virtual" in virtual inheritance doesn't mean the same thing as the
    "virtual" in virtual member functions. If you don't already understand
    virtual inheritance, I suggest looking it up rather than confusing
    yourself by making assumptions about what it does. Also, see Dave
    Rahardja's thread from earlier today "Virtual Inheritance and
    interfaces" for some debate about how it applies to your situation.

    The virtual destructor in IA isn't required, but it is a Good Idea.
    Also, there are some good arguments for why you should have at least one
    virtual function in a class that is not defined inline. Since the
    destructor of IA is the only function with a definition, it might make
    sense not to define it inline as I did.

    --
    Alan Johnson
     
    Alan Johnson, Feb 1, 2007
    #4
  5. On Feb 1, 6:58 am, wrote:
    > Here is what I have so far:


    [snip]

    > When I compile this, I get an error message saying that doA is
    > abstract in class JA????


    Not in JB? I had to make a few changes to get your code through the
    compiler but I never got that error, what I did get was an ambiguity
    in JB if I tried to call doA(), since there's a doA() in both JA and
    in IA (which JB inherits from indirectly through IB). This can be
    solved with a using statement, see code below. This could probably be
    solved in some other way, I'm not a big fan of large inheritance
    hierarchies myself so I've never had this problem. There was a thread
    just the other day about virtual public inheritance which might be
    worth checking out.

    // interface IA
    class IA
    {
    public:
    virtual void doA() throw() = 0;
    };

    // interface IB
    class IB: public IA
    {
    public:
    virtual void doB() throw() = 0;
    };

    // concrete class JA conforming to interface IA
    class JA: public IA
    {
    public:
    JA() { }
    virtual ~JA();
    void doA() throw() { }
    };

    // concrete class JB conforming to interface IB
    class JB: public JA, public IB
    {
    public:
    using JA::doA;

    JB() { }
    virtual ~JB();
    void doB() throw() {doA();}
    };

    --
    Erik Wikström
     
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Feb 1, 2007
    #5
  6. Grizlyk Guest

    Alan Johnson wrote:
    >
    > wrote:
    >>
    >> // concrete class JA conforming to interface IA
    >> public class JA implements IA


    Wrong way in C++. Do not use private inheritance in C++ without concrete
    request, because it is nearly always much better to use composition here:

    template< class IA>
    class JA
    {
    private:
    IA ia;
    }

    >> public class JB extends JB implements IB


    Here the same:

    template< class IB>
    class JB: public interface_JB
    {
    private:
    IB ib;
    }

    >> How do I translate these classes into C++


    --
    Maksim A Polyanin
     
    Grizlyk, Feb 1, 2007
    #6
  7. Grizlyk Guest

    Maybe i was wrong with Java directives, but i hope my reasons are clear -
    use composition instead of C++ multiple inheritance:

    Erik Wikstrom wrote:
    >
    > // interface IA
    > class IA
    > {
    > public:
    > virtual void doA() throw() = 0;
    > };
    >
    > // interface IB
    > class IB: public IA
    > {
    > public:
    > virtual void doB() throw() = 0;
    > };
    >
    > // concrete class JA conforming to interface IA
    > class JA: public IA
    > {
    > public:
    > JA() { }
    > virtual ~JA();
    > void doA() throw() { }
    > };
    >
    > // concrete class JB conforming to interface IB
    > class JB: public JA, public IB


    template<class T=JA>
    class JB: public IB
    {
    T ja;

    > {
    > public:
    > using JA::doA;


    //forwarding here
    void doA() throw() {ja.doA();}

    > JB() { }
    > virtual ~JB();
    > void doB() throw() {doA();}


    //implement here
    void doB() throw();

    > };



    --
    Maksim A Polyanin
     
    Grizlyk, Feb 1, 2007
    #7
  8. Alan Johnson Guest

    Grizlyk wrote:
    > Alan Johnson wrote:
    >> wrote:
    >>> // concrete class JA conforming to interface IA
    >>> public class JA implements IA

    >
    > Wrong way in C++. Do not use private inheritance in C++ without concrete
    > request, because it is nearly always much better to use composition here:
    >
    > template< class IA>
    > class JA
    > {
    > private:
    > IA ia;
    > }


    Where did anybody use private inheritance?

    >
    >>> public class JB extends JB implements IB

    >
    > Here the same:
    >
    > template< class IB>
    > class JB: public interface_JB
    > {
    > private:
    > IB ib;
    > }
    >
    >>> How do I translate these classes into C++

    >


    In your example, what is interface_JB? And what is IB? I can't really
    tell what point you are trying to make. Runtime polymorphism can't be
    achieved with templates and composition in C++.

    --
    Alan Johnson
     
    Alan Johnson, Feb 1, 2007
    #8
  9. Pete Becker Guest

    Alan Johnson wrote:
    > wrote:
    >
    > class JB : public JA, public IB
    > {
    > public:
    > virtual void doB()
    > {
    > std::cout << "JB::doB()" << std::endl ;
    > }
    > } ;
    >


    This works for this particular example, but in general, C++ classes that
    are intended to emulate Java's (misguided) interfaces should be used as
    virtual bases (as in the definition of IB). So:

    class JB : public JA, public virtual IB

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Feb 1, 2007
    #9
  10. Pete Becker Guest

    Grizlyk wrote:
    >
    > template< class IB>
    > class JB: public interface_JB
    > {
    > private:
    > IB ib;
    > }
    >


    The goal is to be able to pass objects of the derived type to a function
    like this:

    void f(const IB&);

    Using IB to define a member doesn't support that.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Feb 1, 2007
    #10
  11. Grizlyk Guest

    Alan Johnson wrote:
    >>>> // concrete class JA conforming to interface IA
    >>>> public class JA implements IA

    >>
    >> Wrong way in C++. Do not use private inheritance in C++ without concrete
    >> request, because it is nearly always much better to use composition here:
    >>
    >> template< class IA>
    >> class JA
    >> {
    >> private:
    >> IA ia;
    >> }

    >
    > Where did anybody use private inheritance?


    Yes, i forget, that Java directives "class JA implements IA" does not mean
    "private inheritance". Look my message dated "12:45":
    >> Grizlyk wrote:
    >>Maybe i was wrong with Java directives, but i hope my reasons are clear -
    >>use composition instead of C++ multiple inheritance


    It means, that independent from Java directives, the Java classes can be
    implemented without multiple inheritance.

    > Runtime polymorphism can't be achieved with templates and composition in
    > C++.


    What do you mean as "runtime polymorphism"? The following expression

    >> public class JB extends JB implements IB


    can not be treated as "runtime polymorphism" (for C++ at least), because
    "class JB " will be created at compile time or am I wrong?

    >>>> How do I translate these classes into C++


    As I could understand, the problem is appearence of multiple inheritence for
    direct Java -> C++ casting and OP wants to avoid it (take in account, I can
    not see whole thread), if yes:
    1. In all cases any kind (ordinary or multiple) of "inheritance of
    implementation" _can_ be replaced by composition (static or dynamic).
    2. In most cases any kind (ordinary or multiple) of "inheritance of
    implementation" _must_ be replaced by composition (static or dynamic),
    because composition (instead of inheritance) increase ability of "reusage"
    of classes.

    Somebody implements the Java classes on C++ like this:
    >>
    >> // interface IA
    >> class IA
    >> {
    >> public:
    >> virtual void doA() throw() = 0;
    >> };
    >>
    >> // interface IB
    >> class IB: public IA
    >> {
    >> public:
    >> virtual void doB() throw() = 0;
    >> };
    >>
    >> // concrete class JA conforming to interface IA
    >> class JA: public IA
    >> {
    >> public:
    >> JA() { }
    >> virtual ~JA();
    >> void doA() throw() { }
    >> };
    >>
    >> // concrete class JB conforming to interface IB
    >> class JB: public JA, public IB


    Here he has used multiple inheritance.

    >In your example, what is interface_JB?

    In the example "interface_JB" is "IB".

    This is my example of static implementation with the help of composition

    template<class IA=JA>
    class JB: public IB
    {
    IA ia;
    public:
    //forwarding
    void doA() throw() {ia.doA();}


    //to implement
    void doB() throw();//{ia.doA();}
    };

    This is my example of dynamic implementation with the help of composition

    template< class IA>
    class JB: public IB
    {
    private:
    IA *ia;

    public:
    //forwarding
    void doA() throw() {ia->doA();}


    //to implement
    void doB() throw();//{ia->doA();}

    public:
    JB( IA *p):ia(p){}
    };

    Note, that explicit throw specification (as "throw(expr)") is not safe in
    current C++ implementation, in the following example:

    void doA() throw() { throw 0; }
    try{ doA(); }catch(...){}

    "throw 0;" will terminate your program.

    --
    Maksim A Polyanin
     
    Grizlyk, Feb 1, 2007
    #11
  12. Grizlyk Guest

    Pete Becker wrote:
    > Grizlyk wrote:
    >>
    >> template< class IB>
    >> class JB: public interface_JB
    >> {
    >> private:
    >> IB ib;
    >> }
    >>

    >
    > The goal is to be able to pass objects of the derived type to a function
    > like this:
    >
    > void f(const IB&);
    >
    > Using IB to define a member doesn't support that.
    >



    No, I was assuming "IB" is derived from "interface_JB". Look here
    news:epsoea$ghu$ (message dated "16:03")

    --
    Maksim A Polyanin
     
    Grizlyk, Feb 1, 2007
    #12
  13. Grizlyk Guest

    Alan Johnson wrote:
    >
    > Where did anybody use private inheritance?
    >


    Here

    >> // concrete class JB conforming to interface IB
    >> class JB: public JA, public IB


    "public JA" is really "inheritance of implementation".

    --
    Maksim A Polyanin
     
    Grizlyk, Feb 1, 2007
    #13
  14. On 31 Jan 2007 21:51:01 -0800, wrote:

    >I have some code in Java that I need to translate into C++. My Java
    >code defines a class hierarchy as follows:


    In general, Java's interface definitions can be implemented in C++ as a class
    with nothing but pure virtual functions (and a public virtual destructor that
    does nothing).

    Java:

    public interface I
    {
    public abstract void fn();
    }

    C++:

    class I // Interface
    {
    public:
    virtual void fn() = 0;
    virtual ~I() {}
    };

    Implementing a Java interface is analogous to virtual public inheritance in
    C++.

    Java:

    public class A implements I
    {
    public void fn() { /* ... */ }
    }

    C++:

    class A: public virtual I
    {
    public:
    virtual void fn() { /* ... */ }
    };


    I started a thread about the pros and cons of performing this analogous
    exercise in C++ about a week ago. Do a search for my name and the topic
    "Virtual inheritance and interfaces".

    -dr
     
    Dave Rahardja, Feb 2, 2007
    #14
    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. Thomas Heller
    Replies:
    13
    Views:
    522
    Bengt Richter
    Jul 8, 2005
  2. Replies:
    2
    Views:
    310
    Mike Schilling
    Oct 11, 2006
  3. josh
    Replies:
    6
    Views:
    454
    Ed Kirwan
    Dec 19, 2006
  4. Veli-Pekka Tätilä
    Replies:
    7
    Views:
    164
    Veli-Pekka Tätilä
    Aug 20, 2005
  5. Henri Sivonen

    Extending the DOM interfaces

    Henri Sivonen, Mar 16, 2005, in forum: Javascript
    Replies:
    2
    Views:
    101
    Martin Honnen
    Mar 17, 2005
Loading...

Share This Page