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 ]