473,729 Members | 2,164 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Why operator<< should be friend or global, non-member function.

>From a book, I know the following is true for the comparison operators:
An overloaded operator that is a class member is only considered
when the operator is used with a *left* operand that is an object
of that class.
And is that also the reason why if you use class member functions for
operators << and >you have to write:
someclass << cout;
someclass >cin;
?

Thus you usually make them friends so you avoid have to use cin and
cout
in such a weird manner.

/ E

Nov 8 '06 #1
7 2795
Eric Lilja wrote:
>From a book, I know the following is true for the comparison
operators:
An overloaded operator that is a class member is only considered
when the operator is used with a *left* operand that is an object
of that class.
And is that also the reason why if you use class member functions for
operators << and >you have to write:
someclass << cout;
someclass >cin;
<BTWActually, I'd expect the "arrows" to be reversed here, IOW

someclass >cout;
someclass << cin;

to correctly show the "direction" of the data flow. </BTW>
?
No, it is not. The actual reason is that if you wanted them as members,
they would have to be members of 'ostream' or 'istream', to which you
have no access. That's why they are usually made non-members. Nobody
in their right mind thinks of making them members of the class to be
streamed.
Thus you usually make them friends so you avoid have to use cin and
cout
in such a weird manner.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 8 '06 #2

Victor Bazarov skrev:
Eric Lilja wrote:
From a book, I know the following is true for the comparison
operators:
An overloaded operator that is a class member is only considered
when the operator is used with a *left* operand that is an object
of that class.
And is that also the reason why if you use class member functions for
operators << and >you have to write:
someclass << cout;
someclass >cin;

<BTWActually, I'd expect the "arrows" to be reversed here, IOW
Oops, sorry about that.
>
someclass >cout;
someclass << cin;

to correctly show the "direction" of the data flow. </BTW>
?

No, it is not. The actual reason is that if you wanted them as members,
Ok, so which operators is the statement true for (An overloaded
operator that is a class member is only considered when the operator is
used with a *left* operand that is an object of that class.)? Only for
comparison operators?
they would have to be members of 'ostream' or 'istream', to which you
have no access. That's why they are usually made non-members. Nobody
in their right mind thinks of making them members of the class to be
streamed.
Thus you usually make them friends so you avoid have to use cin and
cout
in such a weird manner.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
/ E

Nov 8 '06 #3

Victor Bazarov skrev:
Eric Lilja wrote:
From a book, I know the following is true for the comparison
operators:
An overloaded operator that is a class member is only considered
when the operator is used with a *left* operand that is an object
of that class.
And is that also the reason why if you use class member functions for
operators << and >you have to write:
someclass << cout;
someclass >cin;

<BTWActually, I'd expect the "arrows" to be reversed here, IOW

someclass >cout;
someclass << cin;

to correctly show the "direction" of the data flow. </BTW>
?

No, it is not. The actual reason is that if you wanted them as members,
they would have to be members of 'ostream' or 'istream', to which you
have no access. That's why they are usually made non-members. Nobody
in their right mind thinks of making them members of the class to be
streamed.
But wait a minute, it is reason then. You seemed to say that the
statement "An overloaded operator that is a class member is only
considered when the operator is used with a *left* operand that is an
object of that class." is false.
In the form cout << myclass; cout is the left operand, that's why you
said I'd have to change ostream or istream. So the statement above is
true for operator << and >too.
>
Thus you usually make them friends so you avoid have to use cin and
cout
in such a weird manner.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
/ E

Nov 8 '06 #4
Eric Lilja wrote:
Victor Bazarov skrev:
>Eric Lilja wrote:
>>>From a book, I know the following is true for the comparison
operators:
An overloaded operator that is a class member is only considered
when the operator is used with a *left* operand that is an object
of that class.
And is that also the reason why if you use class member functions
for operators << and >you have to write:
someclass << cout;
someclass >cin;

<BTWActually , I'd expect the "arrows" to be reversed here, IOW

someclass >cout;
someclass << cin;

to correctly show the "direction" of the data flow. </BTW>
>>?

No, it is not. The actual reason is that if you wanted them as
members, they would have to be members of 'ostream' or 'istream', to
which you have no access. That's why they are usually made
non-members. Nobody in their right mind thinks of making them
members of the class to be streamed.

But wait a minute, it is reason then. You seemed to say that the
statement "An overloaded operator that is a class member is only
considered when the operator is used with a *left* operand that is an
object of that class." is false.
Huh?

struct A {
A(int);
void operator+(A const&) const;
};

int main() {
A a(42);
a + 73; // compiles OK
666 + a; // cannot compile
}

'666 + a' does not compile because the compilers don't try to convert
the left operand to 'A' (here). That's why in order for '666 + a' to
compile, you need the operator+ to be non-member:

struct A {
A(int);
};

void operator+(A const&, A const&);

int main() {
A a(42);
a + 73; // compiles OK
666 + a; // compile OK
}
In the form cout << myclass; cout is the left operand, that's why you
said I'd have to change ostream or istream. So the statement above is
true for operator << and >too.
You lost me.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 8 '06 #5

Victor Bazarov skrev:
Eric Lilja wrote:
Victor Bazarov skrev:
Eric Lilja wrote:
From a book, I know the following is true for the comparison
operators:
An overloaded operator that is a class member is only considered
when the operator is used with a *left* operand that is an object
of that class.
And is that also the reason why if you use class member functions
for operators << and >you have to write:
someclass << cout;
someclass >cin;

<BTWActually, I'd expect the "arrows" to be reversed here, IOW

someclass >cout;
someclass << cin;

to correctly show the "direction" of the data flow. </BTW>

?

No, it is not. The actual reason is that if you wanted them as
members, they would have to be members of 'ostream' or 'istream', to
which you have no access. That's why they are usually made
non-members. Nobody in their right mind thinks of making them
members of the class to be streamed.
But wait a minute, it is reason then. You seemed to say that the
statement "An overloaded operator that is a class member is only
considered when the operator is used with a *left* operand that is an
object of that class." is false.

Huh?

struct A {
A(int);
void operator+(A const&) const;
};

int main() {
A a(42);
a + 73; // compiles OK
666 + a; // cannot compile
}

'666 + a' does not compile because the compilers don't try to convert
the left operand to 'A' (here). That's why in order for '666 + a' to
compile, you need the operator+ to be non-member:

struct A {
A(int);
};

void operator+(A const&, A const&);

int main() {
A a(42);
a + 73; // compiles OK
666 + a; // compile OK
}
In the form cout << myclass; cout is the left operand, that's why you
said I'd have to change ostream or istream. So the statement above is
true for operator << and >too.

You lost me.
Hehe, ok, I'll try to be a bit more clearer. Just trying to understand
why operator<< (and >>) "has to be" non-member functions for
user-introduced classes if you want to be able to use input and output
streams with objects of those classes in the normal way.
Say we have a class A and we have an instance of A named "a" and we do:
cout << a;
The compiler first check for a global function returning an
ostream-reference and taking two arguments: reference to an ostream and
const reference to class A.
If it finds no such function it translates the call to
cout.operator<< (a) but that fails because ostream doesn't have a member
operator<< that takes our class A. Or maybe it checks the other way
around.
If we make operator<< a member of A we have to write a.operator<<(co ut)
or a << cout;
Thus, the solution is to write a global operator<< (usually declared as
friend for easy access to the class private data members).
Is this "analysis" correct or at least somewhat correct?
>
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
/ E

Nov 9 '06 #6

Eric Lilja wrote:
From a book, I know the following is true for the comparison operators:
An overloaded operator that is a class member is only considered
when the operator is used with a *left* operand that is an object
of that class.
And is that also the reason why if you use class member functions for
operators << and >you have to write:
someclass << cout;
someclass >cin;
?

Thus you usually make them friends so you avoid have to use cin and
cout
in such a weird manner.
Avoid making them friends.

Nov 9 '06 #7
Eric Lilja wrote:
Victor Bazarov skrev:
>Eric Lilja wrote:
>>Victor Bazarov skrev:

Eric Lilja wrote:
>From a book, I know the following is true for the comparison
>operator s:
An overloaded operator that is a class member is only considered
when the operator is used with a *left* operand that is an object
of that class.
And is that also the reason why if you use class member functions
for operators << and >you have to write:
someclass << cout;
someclass >cin;

<BTWActually , I'd expect the "arrows" to be reversed here, IOW

someclass >cout;
someclass << cin;

to correctly show the "direction" of the data flow. </BTW>

?

No, it is not. The actual reason is that if you wanted them as
members, they would have to be members of 'ostream' or 'istream',
to which you have no access. That's why they are usually made
non-members. Nobody in their right mind thinks of making them
members of the class to be streamed.

But wait a minute, it is reason then. You seemed to say that the
statement "An overloaded operator that is a class member is only
considered when the operator is used with a *left* operand that is
an object of that class." is false.

Huh?

struct A {
A(int);
void operator+(A const&) const;
};

int main() {
A a(42);
a + 73; // compiles OK
666 + a; // cannot compile
}

'666 + a' does not compile because the compilers don't try to convert
the left operand to 'A' (here). That's why in order for '666 + a' to
compile, you need the operator+ to be non-member:

struct A {
A(int);
};

void operator+(A const&, A const&);

int main() {
A a(42);
a + 73; // compiles OK
666 + a; // compile OK
}
>>In the form cout << myclass; cout is the left operand, that's why
you said I'd have to change ostream or istream. So the statement
above is true for operator << and >too.

You lost me.

Hehe, ok, I'll try to be a bit more clearer. Just trying to understand
why operator<< (and >>) "has to be" non-member functions for
user-introduced classes if you want to be able to use input and output
streams with objects of those classes in the normal way.
Well, actually, no. You can define your own stream class wrapping
standard stream, then you will be able to add your own operators to
it and "forward" them in any way you want to the wrapped stream.
Say we have a class A and we have an instance of A named "a" and we
do: cout << a;
OK. That's what we do usually.
The compiler first check for a global function returning an
ostream-reference and taking two arguments: reference to an ostream
and const reference to class A.
It first checks the member, actually.
If it finds no such function it translates the call to
cout.operator<< (a) but that fails because ostream doesn't have a
member operator<< that takes our class A. Or maybe it checks the
other way around.
Right. The other way.
If we make operator<< a member of A we have to write
a.operator<<(co ut) or a << cout;
Well, yes, but nobody does it that way.
Thus, the solution is to write a global operator<< (usually declared
as friend for easy access to the class private data members).
Is this "analysis" correct or at least somewhat correct?
Nah, it's fine. You got it.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 9 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2225
by: Dan | last post by:
Hi, I would just like to know if the istream operator takes only one parammeter(object) at a time (like z) ? istream operator>>(istream& in, Shape &z) Cause I keep getting error concerning the amount my operator has for bother cin , cout operator<< and >> thanks Dan
3
1916
by: Alicia | last post by:
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"
5
5012
by: Gianni Mariani | last post by:
Can anyone enligten me why I get the "ambiguous overload" error from the code below: friendop.cpp: In function `int main()': friendop.cpp:36: ambiguous overload for `std::basic_ostream<char, std::char_traits<char> >& << Thing&' operator friendop.cpp:27: candidates are: std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const Thing&) friendop.cpp:14: std::basic_ostream<_CharT, _Traits>&...
5
1875
by: Eric Lilja | last post by:
Ok, this code doesn't compile: #include <iostream> #include <ostream> /* Just for you, Mike :-) */ template<typename T> class Couple { public: Couple(const T& ax, const T& ay) : x(ax), y(ay) {}
4
6747
by: Rock | last post by:
I'm in the process of writing this program for complex numbers and I use DevC++. My professor on the other hand compiles on Borland 5.5. So I ocasionally save and run my work on Borland to see if it caught anything, it's very picky... Anyway, the code below works on Dev, and it compiles fine on Borland, but when I run it from borland, there is no output, no error, it just skips right over the freind ostream call. HELP! I'm new to this...
2
2177
by: Harry | last post by:
Hi all, I am writing a logger program which can take any datatype. namespace recordLog { enum Debug_Level {low, midium, high}; class L { std::ofstream os; Debug_Level cdl; const Debug_Level ddl;
3
1595
by: Yudan Yi \(OSU\) | last post by:
I have a question to define a friend operator<< for a class. for example, I can define friend ostream& operator<<(ostream& os, const TTest& x) { ...; return (os); }; While I want to add more control to the output by an additional parameter, can I do in the following way? friend ostream& operator<<(ostream& os, const TTest& x, unsigned parameter) { switch (parameter)
2
3192
by: ryan_melville | last post by:
Hi, Should I put the operator<<() for my class (which is in a namespace) in the namespace or make it global? If I understand the lookup rules correctly: If I make it global, it may be hidden if called from within a different namespace and that other namespace has any operator<<() defined. That doesn't seem good.
5
2272
by: noone | last post by:
hi. I don't use exceptions much in the embedded world, but for my plugin interface to a hardware MPEG encoder I'd like to, since there are so many places that the crummy kernel driver can do bad things to my userland program. I hope this news client doesn't reformat my example below and make it impossible to read. :^) consider the following exception heirarchy
1
1415
by: Stuart Golodetz | last post by:
Hi guys, I'm trying to making an instance of a templated operator<< for a templated class a friend of that class (see below), to allow it to access the class internals for output purposes. #include <iostream> template <typename T> class TC
0
8927
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8764
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9289
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9156
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8159
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6722
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6026
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
3242
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2694
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.