Accessing inherited operator<< in base class from derived class

Discussion in 'C++' started by Alicia, Nov 23, 2004.

  1. Alicia

    Alicia Guest

    Hello,
    I am trying to figure out how to call an overloaded operator<<
    inherited from a base class.

    #ifndef PHONECALL
    #define PHONECALL

    #include "time.h"
    #include "interval.h"

    enum CallType {LOCAL, LONG_DISTANCE};

    class PhoneCall
    {
    public:
    friend std::istream& operator>>(std::istream& in, PhoneCall&
    phoneCall);
    friend std::eek:stream& operator<<(std::eek:stream& out, const
    PhoneCall& phoneCall);
    CallType getCallType() const;
    int callLength() const;

    private:
    CallType callType;
    Interval<Time> interval;
    };

    #endif


    Here is the inherited class:


    #include "phonecall.h"
    #include "money.h"
    #include <iostream>

    class CostedCall:public PhoneCall
    {
    public:
    CostedCall();
    CostedCall(PhoneCall phoneCall, Money cost);
    friend ostream& operator<<(ostream& out, const CostedCall&
    phonecall);
    private:
    Money cost;
    };

    The output on the base class PhoneCall works correctly. What I need to
    know is how to call the operator<< in the base class PhoneCall from
    the derived class CostedCall. I tried something like this:

    ostream& operator<<(ostream& out,const CostedCall& phonecall)
    {

    PhoneCall::eek:perator<<(out,phonecall);

    return out;
    }

    I am completely lost. Any help would be appreciated.

    Alicia
     
    Alicia, Nov 23, 2004
    #1
    1. Advertising

  2. Alicia wrote in news: in
    comp.lang.c++:

    >
    > ostream& operator<<(ostream& out,const CostedCall& phonecall)
    > {
    >


    It isn't a member so you can't do this:

    > PhoneCall::eek:perator<<(out,phonecall);


    out << static_cast< Phoncall const & >( phonecall );
    >
    > return out;
    > }
    >


    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Nov 23, 2004
    #2
    1. Advertising

  3. Alicia

    Scuro Guest

    Alicia wrote:

    > Hello,
    > I am trying to figure out how to call an overloaded operator<<
    > inherited from a base class.

    *snip*
    > I am completely lost. Any help would be appreciated.
    >
    > Alicia


    Nice question :)

    So, let me simplify your problem:

    class A {
    public:
    friend ostream& operator<<(ostream& out, const A& a){
    // code
    }
    // code
    };

    class B : public A {
    public:
    // code
    friend ostream& operator<<(ostream& out, const B& b){
    // code
    }
    }

    So, what you want to do is something like that:

    A *a=new B();
    cout << *a;
    and you want the operator<< in class B to be called, ok?
    but you can not redefine a function that is not virtual, so you want to
    write:

    class A { // version 1.1
    public:
    virtual friend ostream& operator<<(ostream& out, const A& a){
    // code
    }
    // code
    };

    Ops, you can not make friends virtual, and now?

    class A { // version 1.2
    public:
    virual ostream& operator<<(ostream& out, const A& a){
    // code
    }
    // code
    };

    Ops! operator<< now cannot access private members of A!
    The question is: how to make a virtual and friend function? The answer
    is: separate them!!!

    class A { // version 2.0
    public:
    friend ostream& operator<<(ostream& out, const A& a){
    return a.print(out);
    }
    virtual ostream& print(ostream& out) const {
    out << "A::eek:perator<<" << endl;
    return out;
    }
    };

    And now the class B!

    class B : public A {
    public:
    // code
    ostream& print(ostream& out) const {
    out << "B::eek:perator<<" << endl;
    return out;
    }
    }

    Now, what happens when you do:

    A *a=new B();
    cout << *a;

    1) operator<< (ostream&, A&) is called.
    2) a.print(out) is called, but the type of a is B, so B::print(ostream&)
    is called.

    If you need, you can complete the code adding the operator<< to B too.

    class B : public A {
    public:
    // code
    friend ostream& operator<<(ostream& out, const B& b){
    return b.print(out);
    }
    ostream& print(ostream& out) const {
    out << "B::eek:perator<<" << endl;
    return out;
    }
    }

    This tecnique is called multiple dispatching and it's explained well in
    "thinking in C++".

    Bye!

    P.S.: I have not compiled the code, so i apologize for errors...
     
    Scuro, Nov 24, 2004
    #3
  4. Alicia

    jjr2004a Guest

    A better way to do this is in section 21.2.3.1 "Virtual
    Output Functions" in Stroustrup, 3rd Edition.

    He suggests using a virtual put function which in turn
    used in an operator<< function defined for the base class.

    Here's his example with some added comments:

    // base class header file
    //
    class My_base {
    public:
    virtual ostream& put(ostream& s) const=0
    };

    ostream& operator<<(ostream& s, const My_base& r)
    {
    // uses the right put()
    return r.put(s);
    }

    // derived class header file
    //
    class Sometype : public My_base {
    public:
    // override My_base::put()
    ostream& put(ostreasm& s) const;
    };


    // some other .cpp file
    //
    void f(const My_base& r, Sometype& s)
    {
    // use << which calls the right put()
    std::cout << r << s;
    }
     
    jjr2004a, Nov 24, 2004
    #4
    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. Abhijit Deshpande
    Replies:
    7
    Views:
    11,779
    samualmenon
    Jul 16, 2008
  2. Replies:
    1
    Views:
    412
    myork
    May 23, 2007
  3. Replies:
    1
    Views:
    400
    Victor Bazarov
    May 23, 2007
  4. Bhawna
    Replies:
    7
    Views:
    489
    Bhawna
    Aug 26, 2008
  5. 7stud --
    Replies:
    11
    Views:
    448
    7stud --
    Nov 9, 2007
Loading...

Share This Page