REQ: how to override 2 virtual functions with the same name and same parameter

Discussion in 'C++' started by zzppallas@gmail.com, Feb 6, 2006.

  1. Guest

    I have interface A and interface B decalared as follow:
    class A
    {
    public:
    virtual void OnError(std::string reson) = 0;
    };

    class B
    {
    public:
    virtual void OnError(std::string reson) = 0;
    };

    And I want to construct a class c inherit both from A and B;

    class C: public A, public B
    {
    public:
    void OnError(std::string reson); // for A
    void OnError(std::string reson); // for B
    };

    any one can help me how to implement 2 OnError, one for interface A and
    one for Interface B

    thanx for ur help
    , Feb 6, 2006
    #1
    1. Advertising

  2. Luke Meyers Guest

    wrote:
    > I have interface A and interface B decalared as follow:
    > class A
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > class B
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > And I want to construct a class c inherit both from A and B;
    >
    > class C: public A, public B
    > {
    > public:
    > void OnError(std::string reson); // for A
    > void OnError(std::string reson); // for B
    > };
    >
    > any one can help me how to implement 2 OnError, one for interface A and
    > one for Interface B


    You can't. C++ forbids the definition of two different functions in
    the same namespace with the same signature. You can't overload based
    on which parent you've got in mind. How would client code distinguish
    between them (when not using a pointer-to-base)?

    Luke
    Luke Meyers, Feb 6, 2006
    #2
    1. Advertising

  3. Jaspreet Guest

    wrote:
    > I have interface A and interface B decalared as follow:
    > class A
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > class B
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > And I want to construct a class c inherit both from A and B;
    >
    > class C: public A, public B
    > {
    > public:
    > void OnError(std::string reson); // for A
    > void OnError(std::string reson); // for B
    > };
    >
    > any one can help me how to implement 2 OnError, one for interface A and
    > one for Interface B
    >
    > thanx for ur help


    You can use 2 different functions with the same signature only in 2
    different namespaces. I do not think you could have the above code
    since how would the user differentiate between which OnError() do you
    want to use.
    Jaspreet, Feb 6, 2006
    #3
  4. * :
    > I have interface A and interface B decalared as follow:
    > class A
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > class B
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > And I want to construct a class c inherit both from A and B;
    >
    > class C: public A, public B
    > {
    > public:
    > void OnError(std::string reson); // for A
    > void OnError(std::string reson); // for B
    > };
    >
    > any one can help me how to implement 2 OnError, one for interface A and
    > one for Interface B


    How should the caller indicate which one to call? That would be
    impossible. Hence you need to do something else, such as using
    composition instead of inheritance:

    class C;

    class CA: public A { friend class C; ... };
    class CB: public B { friend class C; ... };

    class C
    {
    public:
    CA a;
    CB b;
    };

    Here the purpose of class C is simply to coordinate the CA and CB
    instances and provide code that is common to both. Typically you'd pass
    a reference to the C object to the CA and the CB constructors.

    Btw., that std::string argument should really be passed as a std::string
    const&, and inheritance of the interfaces should probably be virtual.

    Hth.,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Feb 6, 2006
    #4
  5. Re: REQ: how to override 2 virtual functions with the same name andsame parameter

    wrote:
    > I have interface A and interface B decalared as follow:
    > class A
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > class B
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > And I want to construct a class c inherit both from A and B;
    >
    > class C: public A, public B
    > {
    > public:
    > void OnError(std::string reson); // for A
    > void OnError(std::string reson); // for B
    > };
    >
    > any one can help me how to implement 2 OnError, one for interface A and
    > one for Interface B


    Like this:

    class A
    {
    public:
    virtual void OnError(std::string reson) = 0;
    };

    class B
    {
    public:
    virtual void OnError(std::string reson) = 0;
    };

    class A_proxy
    : A
    {
    public:
    virtual void OnErrorA(std::string reson) = 0;
    virtual void OnError(std::string reson)
    {
    OnErrorA( reason );
    }
    };

    class B_Proxy
    : B
    {
    public:
    virtual void OnErrorB(std::string reson) = 0;
    virtual void OnError(std::string reson)
    {
    OnErrorB( reason );
    }
    };


    class C: public A_Proxy, public B_Proxy
    {
    public:
    void OnErrorA(std::string reson); // for A
    void OnErrorB(std::string reson); // for B
    };
    Gianni Mariani, Feb 6, 2006
    #5
  6. Re: REQ: how to override 2 virtual functions with the same name and same parameter

    * Gianni Mariani:
    > wrote:
    > > I have interface A and interface B decalared as follow:
    > > class A
    > > {
    > > public:
    > > virtual void OnError(std::string reson) = 0;
    > > };
    > >
    > > class B
    > > {
    > > public:
    > > virtual void OnError(std::string reson) = 0;
    > > };
    > >
    > > And I want to construct a class c inherit both from A and B;
    > >
    > > class C: public A, public B
    > > {
    > > public:
    > > void OnError(std::string reson); // for A
    > > void OnError(std::string reson); // for B
    > > };
    > >
    > > any one can help me how to implement 2 OnError, one for interface A and
    > > one for Interface B

    >
    > Like this:
    >
    > class A
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > class B
    > {
    > public:
    > virtual void OnError(std::string reson) = 0;
    > };
    >
    > class A_proxy
    > : A
    > {
    > public:
    > virtual void OnErrorA(std::string reson) = 0;
    > virtual void OnError(std::string reson)
    > {
    > OnErrorA( reason );
    > }
    > };
    >
    > class B_Proxy
    > : B
    > {
    > public:
    > virtual void OnErrorB(std::string reson) = 0;
    > virtual void OnError(std::string reson)
    > {
    > OnErrorB( reason );
    > }
    > };
    >
    > class C: public A_Proxy, public B_Proxy
    > {
    > public:
    > void OnErrorA(std::string reson); // for A
    > void OnErrorB(std::string reson); // for B
    > };


    I'll assume that you mean public inheritance all the way since A and B
    are interfaces, not classes to inherit implementations from.

    The above then works technically but there is a design problem, namely
    that class C says it "is a" A and "is a" B, but if you pass a C instance
    to template code that assumes A (or B) it clearly isn't, for calls to
    OnError in the template code will then give compile time errors.

    That can be technically solved by casting in the code that passes in the
    C instance.

    Essentially that casting means recognizing in the client code that C
    isn't really an A or B, but a composition expressed using C++
    inheritance: that class C itself doesn't have e.g. OnError.

    For that reason I think actual C++ level composition is just as good a
    choice. The C++ code then corresponds directly to the design, and makes
    the design explicit, not something to be figured out. However, it's a
    little more to write to implement it that way, so it's not clear-cut.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Feb 6, 2006
    #6
    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. Joshua
    Replies:
    8
    Views:
    6,020
    Joshua
    Sep 29, 2004
  2. Ruben Van Havermaet

    Override virtual member functions in Subclasses

    Ruben Van Havermaet, Aug 3, 2004, in forum: C++
    Replies:
    22
    Views:
    855
    jeffc
    Aug 4, 2004
  3. John Goche
    Replies:
    10
    Views:
    722
    Marcus Kwok
    Dec 8, 2006
  4. puzzlecracker
    Replies:
    8
    Views:
    897
    werasm
    Sep 29, 2007
  5. Chris Gordon-Smith
    Replies:
    20
    Views:
    895
    Daniel Pitts
    May 29, 2008
Loading...

Share This Page