Friend functions not inherited

Discussion in 'C++' started by Andrea Crotti, Nov 4, 2010.

  1. To my surprise I read that some time ago, so what I thought it could
    work in fact it could not work.

    Supposing I have two classes

    class Base
    friend operator<<(..)
    // print base fields

    class Extended : Base

    Since the friend is not inherited I guess I have to declare it again,
    but supposing I want to
    - first call the << on the base class
    - then call on the extended class

    how should I do that?
    A cast from the object itself ot it's base type?
     
    Andrea Crotti, Nov 4, 2010
    #1
    1. Advertising

  2. * Andrea Crotti, on 04.11.2010 11:37:
    > To my surprise I read that some time ago, so what I thought it could
    > work in fact it could not work.
    >
    > Supposing I have two classes
    >
    > class Base
    > friend operator<<(..)
    > // print base fields
    >
    > class Extended : Base
    >
    > Since the friend is not inherited I guess I have to declare it again,
    > but supposing I want to
    > - first call the<< on the base class
    > - then call on the extended class
    >
    > how should I do that?
    > A cast from the object itself ot it's base type?


    Please post a minimal and complete example that exemplifies the problem.

    See the FAQ item about how to post a question about Code That Does Not Work.


    Cheers & hth.

    - Alf

    --
    blog at <url: http://alfps.wordpress.com>
     
    Alf P. Steinbach /Usenet, Nov 4, 2010
    #2
    1. Advertising

  3. "Alf P. Steinbach /Usenet" <> writes:

    >
    > Please post a minimal and complete example that exemplifies the problem.
    >
    > See the FAQ item about how to post a question about Code That Does Not Work.
    >
    >
    > Cheers & hth.
    >
    > - Alf


    Nothing in particular that doesn't work, but this is what I wanted to do

    --8<---------------cut here---------------start------------->8---
    #include <iostream>

    using namespace std;

    class Base
    {
    friend ostream& operator<<(ostream& s, const Base& c);
    };

    class Extended : public Base
    {
    };

    ostream& operator<<(ostream& s, const Base& b)
    {
    s << "base class" << endl;
    return s;
    }

    ostream& operator<<(ostream& s, const Extended& e)
    {
    s << (*((Base *) &e)) << endl;
    }

    int main() {
    Extended e;
    cout << e;
    return 0;
    }
    --8<---------------cut here---------------end--------------->8---

    Which is rather ugly, is there a more automatic way to call something on
    the base class in friend operators?
     
    Andrea Crotti, Nov 4, 2010
    #3
  4. "Daniel T." <> writes:

    > What's wrong with doing this?
    >
    > class Base {
    > friend ostream& operator<<(ostream& s, const Base& c);
    > };
    >
    > class Extended : public Base { };
    >
    > ostream& operator<<(ostream& s, const Base& b) {
    > s << "base class" << endl;
    > return s;
    > }
    >
    > int main() {
    > Extended e;
    > cout << e << '\n';
    > }
    >
    > The above compiles fine and does what you wanted.


    Right it does :)
    I guess than that what I found on the internet was just wrong...
     
    Andrea Crotti, Nov 4, 2010
    #4
  5. "Daniel T." <> writes:

    >
    > What's wrong with doing this?
    >
    > class Base {
    > friend ostream& operator<<(ostream& s, const Base& c);
    > };
    >
    > class Extended : public Base { };
    >
    > ostream& operator<<(ostream& s, const Base& b) {
    > s << "base class" << endl;
    > return s;
    > }
    >
    > int main() {
    > Extended e;
    > cout << e << '\n';
    > }
    >
    > The above compiles fine and does what you wanted.



    and what if you want instead want to print
    "extended class base class"

    So first calling the specialized method and from it the base class?

    How do I tell to use Base::eek:perator<< in that case?
     
    Andrea Crotti, Nov 4, 2010
    #5
  6. Andrea Crotti <> wrote:
    > I guess than that what I found on the internet was just wrong...


    No, it was not wrong. You simply misunderstood it.

    The point is that the friend function in your example doesn't *need*
    to be inherited to the derived class in order for it to work properly.
     
    Juha Nieminen, Nov 4, 2010
    #6
  7. On 11/4/2010 8:10 AM, Andrea Crotti wrote:
    > "Daniel T."<> writes:
    >
    >>
    >> What's wrong with doing this?
    >>
    >> class Base {
    >> friend ostream& operator<<(ostream& s, const Base& c);
    >> };
    >>
    >> class Extended : public Base { };
    >>
    >> ostream& operator<<(ostream& s, const Base& b) {
    >> s<< "base class"<< endl;
    >> return s;
    >> }
    >>
    >> int main() {
    >> Extended e;
    >> cout<< e<< '\n';
    >> }
    >>
    >> The above compiles fine and does what you wanted.

    >
    >
    > and what if you want instead want to print
    > "extended class base class"
    >
    > So first calling the specialized method and from it the base class?
    >
    > How do I tell to use Base::eek:perator<< in that case?


    You need to introduce polymorphism and call a virtual function in the
    class Base. Something like

    class Base {
    ...
    virtual ostream& print(ostream& os) const
    {
    return os << "base class";
    }
    };

    class Extended : public Base {
    ostream& print(ostream& os) const
    {
    os << "extended class ";
    return Base::print(os);
    }
    };

    ostream& operator << (ostream& os, const Base& c)
    {
    return c.print(os);
    }

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Nov 4, 2010
    #7
  8. "Daniel T." <> writes:

    > You could do as Victor Bazarov suggested, but the following might be
    > simpler:
    >
    > class Base { };
    >
    > class Extended : public Base { };
    >
    > ostream& operator<<(ostream& s, const Base& b) {
    > s << "base class" << endl;
    > return s;
    > }
    >
    > ostream& operator<<(ostream& s, const Extended& b) {
    > s << static_cast<const Base&>(b);
    > s << "extended class" << endl;
    > return s;
    > }
    >
    > int main() {
    > Extended e;
    > cout << e << '\n';
    > }


    Ah yes I like this solution also thanks!
     
    Andrea Crotti, Nov 5, 2010
    #8
    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. Xiangliang Meng
    Replies:
    1
    Views:
    1,631
    Victor Bazarov
    Jun 21, 2004
  2. ashok
    Replies:
    14
    Views:
    736
    Marcelo Pinto
    Nov 10, 2004
  3. ciccio
    Replies:
    4
    Views:
    471
    ciccio
    Jan 18, 2008
  4. 7stud --
    Replies:
    11
    Views:
    427
    7stud --
    Nov 9, 2007
  5. Peter
    Replies:
    2
    Views:
    287
    Öö Tiib
    Jun 6, 2013
Loading...

Share This Page