Topic: friend operator and the this pointer


Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1996/10/28
Raw View
Nico Josuttis wrote:
>
> Friendship is generally not inherited. So DON'T USE FRIENDS with inheritance
> (therefore it is almost better not to use friend anyhow).

Why ? friend, like public can be used to remove encapsulation or to
improve it.

In particular one friend operator<< does not break encapsulation since
it is part of the class public methods. [Anyway what is good style and
such religious wars are probably more appropriate for
comp.lang.c++.moderated. ]

> I know that several people do it this way, but now you see why you shouldn't.
> The common solution is:
>
> class A
> {
>     public:
>         virtual void printOn (ostream& o) {
>                 /* print the data */
>                 /* e.g. call display(o) */
>         }
>         ...
> };
>
> inline ostream& operator<<(ostream& o, A& a)
> {
>         a.printOn( &o);
>         return o;
> }
>
> class B: public A
> {
>     public:
>         virtual void printOn (ostream& o) {
>                 /* print the data */
>                 /* e.g. call display(o) */
>         }
>         ...
> };

Right but printOn could as well be private and operator<< a friend
of A; both way of doing things are correct.

--

Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: abell@atl.mindspring.com (Andrew C. Bell)
Date: 1996/10/21
Raw View
Fabio Ortiz <jfabio@mailhost.netrunner.net> wrote:
>Hi, I have the following:
> class A { [...] };
>class B: public A
>{
>  [...]
> virtual void display( ostream& o)
> {
>  o << (A*) this;
>  o << myValue;
> }

You don't want to display a pointer to A; replace the first line of
the function with
 o << (A &) *this;
Also, display should *not* be virtual; otherwise, when you "fix" what
you have here, the C << operator calls display on a B, which because
it's virtual, calls C::display(..), which starts the loop all over
again.

>this code only displays the parameter value. It do not call the other
>operators << for some reason. Is There any thing wrong with the cast.

You left out enough, and enough was wrong, that this cannot have been
a straight copy of your source.  Without that I cannot tell you what
exactly caused the results you got.

>Friend functions are not inherited does this mean that I can not call
>them through the this pointer using the cast?.

Even a temporary created by casting has all "rights and privileges" of
that class, including friend relationships.  (If it did not, you would
get a compiler error anyway, not a replacement of the function call
with a no-op.)

>Does it make sense to make a private method virtual, it can not be
>called from the derived functions

Well, in this case it definitely didn't (just take out all your
virtuals.)  However, access control is relevant only for "direct" use.

For example:

class A { private: virtual void Foo() {} public: void Goo() { Foo(); }
};
class B : public A { public: virtual void Foo() {} };

void Bar(B *b)
{
 b->Foo(); // legal
 A *a = b;
 a->Foo(); // compiler error -- cannot access private member
 a->Goo(); // legal -- will call B::Foo() if b truly pointed to
// a B
}

"private" does not hide the names, it just restricts the access.

Results all verified with MSVC++ 4.2.

Andrew Bell
abell@mindspring.com andrewb@graphsoft.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Nico Josuttis <nico@bredex.de>
Date: 1996/10/22
Raw View
Friendship is generally not inherited. So DON'T USE FRIENDS with inheritance
(therefore it is almost better not to use friend anyhow).
I know that several people do it this way, but now you see why you shouldn't.
The common solution is:

class A
{
    public:
 virtual void printOn (ostream& o) {
  /* print the data */
  /* e.g. call display(o) */
 }
 ...
};

inline ostream& operator<<(ostream& o, A& a)
{
 a.printOn( &o);
 return o;
}


class B: public A
{
    public:
 virtual void printOn (ostream& o) {
  /* print the data */
  /* e.g. call display(o) */
 }
 ...
};


Hope this helps
--
Nico                             address: BREDEX GmbH, Nicolai Josuttis
email:   nico@bredex.de                   Fallersleber-Tor-Wall 23
phone:   +49 531 24330-0                  D-38100 Braunschweig
fax:     +49 531 24330-99                 Germany
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Fabio Ortiz <jfabio@mailhost.netrunner.net>
Date: 1996/10/18
Raw View
Hi, I have the following:

class A
{
public:
 A( char* name );
 friend ostream& operator<<(ostream& o, A& a)
  {
   a.display( &o);
   return o;
  }
protected:
 char* myName;
private:
 virtual void display( ostream& o)
 {
  o << myName;
 }
}

class B: public A
{
public:
 B( int value, char* name );
 ostream& operator<<(ostream& o, B& b)
 {
  b.display( o );
  return o;
 }
protected:
 int myValue;
private:
 virtual void display( ostream& o)
 {
  o << (A*) this;
  o << myValue;
 }

class C: public B
{
public:
 C( long number, int value, char* name);
 ostream& operator<<(ostream& o, C& c)
 {
  o << c.display( ostream& o);
  return o;
 }
protected:
 long parameter;
private:
 virtual void display( ostream& o)
 {
  o << (B*) this;
  o << parameter;
 }
}

main()
{
C myC( 20, 10, "aname');
cout << C;
}

this code only displays the parameter value. It do not call the other
operators << for some reason. Is There any thing wrong with the cast.

Friend functions are not inherited does this mean that I can not call
them through the this pointer using the cast?.

I am setting some of the fields using cout.setf( io::hex ) after I use
the cast I do not think this has any effect in the problem.

Does it make sense to make a private method virtual, it can not be
called from the derived functions



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]