Reputation: 13
I wanted to learn how to use friend functions. When attempting it for the first time, I have little problem and I don't know how to fix it. I got the following errors:
|17|error: 'minutes' was not declared in this scope|
|18|error: 'hours' was not declared in this scope|
|24|error: 'minutes' was not declared in this scope|
|24|error: 'minutes' was not declared in this scope|
Here's is all the code I have as of now:
#include <iostream>
using namespace std;
class Time
{
int hours;
int minutes;
friend Time operator+(const Time & t);
friend void x(Time h, Time m );
};
Time operator+(const Time & t)
{
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
void x(Time h, Time m) {hours = h; minutes = m;}
Upvotes: 1
Views: 213
Reputation: 122350
When you write:
class Time
{
friend Time operator+(const Time & t);
};
Then operator+
is not a member function. It is a free function and the line in the class declaration only declares that this function is a friend of the class Time
.
As a non-member, the binary operator+
has to take 2 parameters. Consider how you would use it:
Time a,b;
Time c = a + b;
You need to pass a
and b
and return a new Time
c
:
Time operator+(const Time & t1,const Time& t2)
{
Time sum;
sum.minutes = t1.minutes + t2.minutes;
sum.hours = t1.hours + t2.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}
You have similar problem with x
, but I don't understand what it is supposed to do. If you understand the issue with operator+
you should also be able to fix that.
Upvotes: 1
Reputation: 2552
friend
functions/classes are functions/classes that can access private
and protected
members.
A friend function is not a member function f the class it is declared friend of so it doesn't have the implicit pointer this
so in:
void x(Time h, Time m) {hours = h; minutes = m;} // doesn't compile
Because as long as hours
and minutes
are data members of an object of type class Time
you need to access them via an object of that class.
let' assume your class Time
has a member function named setMinutes()
which is defined as:
int Times::SetMinutes(int h, int m)
{
hours = h; // in fact it is translated as: this->hours = h;
this->minutes = m;
}
As you may have seen the insertion operator <<
be overloaded by a class this way:
friend std:ostream& operator<<(std::ostream& out, const Time& rhs) // friend here is only to access private and protected members
{
out << rhs.hours << " " << rhs.minutes; // not out << hours << minutes; * if the keyword `friend` is removed then this line will not compile: "accessing private members".
return out;
}
Also the declaration of +
operator is incorrect:
friend Time operator+(const Time & t);
Because +
is a binary operator thus it needs two operands "lhs" and "rhs" so you can:
friend Time operator+(const Time & lsh, const Time& rhs);
Or:
Time operator+(const Time & t); // OK
The second version works because the +
is a member function: which means it uses the object on which the operator called as the "lhs" through de-referencing this
and the argument t
as "rhs".
The preferred version is the friend
one.
Upvotes: 0
Reputation: 310960
These error messages
|17|error: 'minutes' was not declared in this scope|
|18|error: 'hours' was not declared in this scope|
means that within this function definition
Time operator+(const Time & t)
{
Time sum;
sum.minutes = minutes + t.minutes;
^^^^^^^
sum.hours = hours + t.hours + sum.minutes / 60;
^^^^^
sum.minutes %= 60;
return sum;
}
the variables minutes
and hours
are not declared. The function is not a member function of the class. So these variables are not data members of an object of the class Time
. They are undeclared identifiers.
Friend functions do not get the implicit argument this
as non-static member class functions do.
These error messages
|24|error: 'minutes' was not declared in this scope|
|24|error: 'minutes' was not declared in this scope|
have the same meaning. The function x
is not a member function of the class Time.
If the friend function operator +
overloads the binary operator +
then it shall have two parameters.
As for the second friend function then it seems its task is to set values for an object of the type Time
.
The friend functions should be declared and defined the following way as it is shown in the demonstrative program below.
#include <iostream>
#include <iomanip>
class Time
{
int hours;
int minutes;
friend Time operator +( const Time &t1, const Time &t2 );
friend void x( Time &t, int h, int m );
friend std::ostream & operator <<( std::ostream &is, const Time &t );
};
Time operator +( const Time &t1, const Time &t2 )
{
const int HOURS_IN_DAY = 24;
const int MINUTES_IN_HOUR = 60;
Time t;
t.hours = t1.hours + t2.hours + ( t1.minutes + t2.minutes ) / MINUTES_IN_HOUR;
t.hours %= HOURS_IN_DAY;
t.minutes = ( t1.minutes + t2.minutes ) % MINUTES_IN_HOUR;
return t;
}
void x( Time &t, int h, int m )
{
t.hours = h;
t.minutes = m;
}
std::ostream & operator <<( std::ostream &os, const Time &t )
{
return
os << std::setw( 2 ) << std::setfill( '0' ) << t.hours
<< ':'
<< std::setw( 2 ) << std::setfill( '0' ) << t.minutes;
}
int main()
{
Time t1;
x( t1, 16, 10 );
std::cout << t1 << '\n';
Time t2;
x( t2, 10, 20 );
std::cout << t2 << '\n';
std::cout << t1 + t2 << '\n';
return 0;
}
The program output is
16:10
10:20
02:30
Upvotes: 2