why overload operator as friend ?

T

Teddy

Hello all

consider the class Date declaretion below:

class Date {
public:
Date();
Date(int year, int month, int day);
Date(const string&);
int getYear() const;
int getMonth() const;
int getDay() const;

friend bool operator<(const Date&, const Date&);
friend bool operator>(const Date&, const Date&);
friend bool operator<=(const Date&, const Date&);
friend bool operator>=(const Date&, const Date&);
friend bool operator==(const Date&, const Date&);
friend bool operator!=(const Date&, const Date&);

private:
int years;
int months;
int days;
};

Can I remove the keyword friend in the six overload operator
declaretions?
If I did so, would they still act the same?
 
L

Leonhard Vogt

Teddy said:
Hello all

consider the class Date declaretion below:

class Date {
public: [...]
int getYear() const;
int getMonth() const;
int getDay() const;

friend bool operator<(const Date&, const Date&);
friend bool operator>(const Date&, const Date&); [...]
private:
int years;
int months;
int days;
};

Can I remove the keyword friend in the six overload operator
declaretions?

Yes you can, but then there is no need (or not even legal?) to place
them inside the class.
If I did so, would they still act the same?

Depends on how you have implemented them, if you don't declare them
as a friend you will not be able to access the private data members
directly, but only via the public access functions.

Leonhard
 
V

velthuijsen

Teddy said:
Hello all

consider the class Date declaretion below:

class Date {
public:
Date();
Date(int year, int month, int day);
Date(const string&);
int getYear() const;
int getMonth() const;
int getDay() const;

friend bool operator<(const Date&, const Date&);
friend bool operator>(const Date&, const Date&);
friend bool operator<=(const Date&, const Date&);
friend bool operator>=(const Date&, const Date&);
friend bool operator==(const Date&, const Date&);
friend bool operator!=(const Date&, const Date&);

private:
int years;
int months;
int days;
};

Can I remove the keyword friend in the six overload operator
declaretions?
No. You'd get a complaint that you cannot have a binary version of the
operator at this point in the file.
If you'd alter the entire thing to:
bool operator<op type>(const Date&) const;
and alter the function body to work within the class then it would work
again.
If I did so, would they still act the same?
Yes. If done correctly the user should not be able to see any
difference in you switching from the binary version to the unary (in
this case).

You should be able to go to the unary versions of the operators seeing
that you have left and right as the same class.
Generally binary versions are used for things like:
friend operator<op type>(const <type1>&, const <type2>&);
friend operator<op type>(const <type2>&, const <type1>&);
 
V

velthuijsen

I need to think out these replies a bit more.

operator<op type>(const <class>&) const;
is still binary (it gets a hidden *this added to the function, which is
also the reason why
operator<op type>(const <class>&, const <class>&);
complains, it expects 2 input vars and gets 3

Why doesn't this happen if you do
friend operator<op type>(const <class>&, const <class>&);
Because you tell your class that a function with this prototype has
full access
to the non public parts of your class.
 
H

Howard

Teddy said:
Hello all

consider the class Date declaretion below:

class Date {
public:
Date();
Date(int year, int month, int day);
Date(const string&);
int getYear() const;
int getMonth() const;
int getDay() const;

friend bool operator<(const Date&, const Date&);
friend bool operator>(const Date&, const Date&);
friend bool operator<=(const Date&, const Date&);
friend bool operator>=(const Date&, const Date&);
friend bool operator==(const Date&, const Date&);
friend bool operator!=(const Date&, const Date&);

private:
int years;
int months;
int days;
};

Can I remove the keyword friend in the six overload operator
declaretions?
If I did so, would they still act the same?

I see that you have public accessor functions for the private members. So,
if you remove those friend declarations entirely and just define the
functions globally (outside the class), then they can use the accessor
functions (e.g., getYear) to make their comparisons.

But if you simply remove the friend specifier, then suddenly those become
member function declarations, and you need to modify the function
definitions and parameter lists accordingly.

-Howard
 
S

Swampmonster

I need to think out these replies a bit more.

operator<op type>(const <class>&) const;
is still binary (it gets a hidden *this added to the function, which is
also the reason why
operator<op type>(const <class>&, const <class>&);
complains, it expects 2 input vars and gets 3

Why doesn't this happen if you do
friend operator<op type>(const <class>&, const <class>&);
Because you tell your class that a function with this prototype has
full access
to the non public parts of your class.

if you do:

class foo {
...
return_type operator op_type (const foo&, const foo&);

you tell the compiler that there is a _member_ function "operator<op
type>" that returns a "return_type" and accepts an implicit "this"
pointer and 2 explicit arguments of type "const foo&". therefor the
compiler will complain because you're declaring a binary operator that
get's passed 3 arguments (1 implicit "this", 2 explicit).

if you do:

class foo {
...
_friend_ return_type operator op_type (const foo&, const foo&);

you tell the compiler that the _free_ function "return_type operator
op_type(..." is a friend of class "foo".
i.e. your allow it access to all protected and private members of "foo".
and since _free_ functions are not members of any class they have no
implicit "this" pointer, and hence the 2 arguments are ok (except for
unary operators of course).

--

in the first case (after you remove the 2nd "const foo&" argument) you'd
have to define the member function like this:

return_type foo::eek:perator op_type (const foo& right)
{
// compare "*this" vs. "right"
...

i.e. qualify the name with "foo::" since the function is a member of
foo. in the second case you don't have to qualify the name (since it's a
_free_ function) and only write:

return_type operator op_type (const foo& left, const foo& right)
{
// compare "left" vs. "right"
...

and finally, if you only need "public" access in your _free_ operator
function, then you can simply delete the whole friend declaration from
the "foo" class - but you need to delete the whole line, not just the
"friend" keyword. if you just delete the "friend" keyword you will
change a "friend declaration" into a "member function declaration" which
are 2 completely different things. they look similar, but they are not.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top