友元函数的工作原理
How friend function works
我想学习如何使用 friend 函数。第一次尝试时,我遇到的问题很少,而且我不知道如何解决。我收到以下错误:
|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|
这是我目前拥有的所有代码:
#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;}
当你写:
class Time
{
friend Time operator+(const Time & t);
};
则operator+
不是成员函数。它是一个自由函数,class 声明中的行仅声明此函数是 class Time
.
的友元
作为非成员,二进制 operator+
必须采用 2 个参数。考虑一下您将如何使用它:
Time a,b;
Time c = a + b;
您需要传递 a
和 b
以及 return 一个新的 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;
}
您对 x
也有类似的问题,但我不明白它应该做什么。如果您了解 operator+
的问题,您应该也能解决这个问题。
这些错误信息
|17|error: 'minutes' was not declared in this scope|
|18|error: 'hours' was not declared in this scope|
表示在这个函数定义内
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;
}
未声明变量 minutes
和 hours
。该函数不是 class 的成员函数。所以这些变量不是classTime
对象的数据成员。它们是未声明的标识符。
友元函数不像非静态成员 class 函数那样获取隐式参数 this
。
这些错误信息
|24|error: 'minutes' was not declared in this scope|
|24|error: 'minutes' was not declared in this scope|
同义。函数 x
不是 class 时间的成员函数。
如果友元函数operator +
重载二元运算符+
,那么它应该有两个参数。
至于第二个友元函数,它的任务似乎是为 Time
.
类型的对象设置值
友元函数应该按照下面的演示程序所示的方式声明和定义。
#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;
}
程序输出为
16:10
10:20
02:30
friend
functions/classes 是 functions/classes 可以访问 private
和 protected
成员。
友元函数不是 class 的成员函数,它被声明为友元函数,因此它没有隐式指针 this
所以在:
void x(Time h, Time m) {hours = h; minutes = m;} // doesn't compile
因为只要 hours
和 minutes
是 class Time
类型对象的数据成员,您就需要通过 class.
假设您的 class Time
有一个名为 setMinutes()
的成员函数,其定义为:
int Times::SetMinutes(int h, int m)
{
hours = h; // in fact it is translated as: this->hours = h;
this->minutes = m;
}
您可能已经看到插入运算符 <<
被 class 以这种方式重载:
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;
}
另外 +
运算符的声明不正确:
friend Time operator+(const Time & t);
因为+
是一个二元运算符所以它需要两个操作数"lhs"和"rhs"所以你可以:
friend Time operator+(const Time & lsh, const Time& rhs);
或者:
Time operator+(const Time & t); // OK
第二个版本有效,因为 +
是一个成员函数:这意味着它通过取消引用 [=] 使用运算符调用的对象作为 "lhs" 19=] 和参数 t
为 "rhs".
首选版本是 friend
。
我想学习如何使用 friend 函数。第一次尝试时,我遇到的问题很少,而且我不知道如何解决。我收到以下错误:
|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|
这是我目前拥有的所有代码:
#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;}
当你写:
class Time
{
friend Time operator+(const Time & t);
};
则operator+
不是成员函数。它是一个自由函数,class 声明中的行仅声明此函数是 class Time
.
作为非成员,二进制 operator+
必须采用 2 个参数。考虑一下您将如何使用它:
Time a,b;
Time c = a + b;
您需要传递 a
和 b
以及 return 一个新的 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;
}
您对 x
也有类似的问题,但我不明白它应该做什么。如果您了解 operator+
的问题,您应该也能解决这个问题。
这些错误信息
|17|error: 'minutes' was not declared in this scope|
|18|error: 'hours' was not declared in this scope|
表示在这个函数定义内
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;
}
未声明变量 minutes
和 hours
。该函数不是 class 的成员函数。所以这些变量不是classTime
对象的数据成员。它们是未声明的标识符。
友元函数不像非静态成员 class 函数那样获取隐式参数 this
。
这些错误信息
|24|error: 'minutes' was not declared in this scope|
|24|error: 'minutes' was not declared in this scope|
同义。函数 x
不是 class 时间的成员函数。
如果友元函数operator +
重载二元运算符+
,那么它应该有两个参数。
至于第二个友元函数,它的任务似乎是为 Time
.
友元函数应该按照下面的演示程序所示的方式声明和定义。
#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;
}
程序输出为
16:10
10:20
02:30
friend
functions/classes 是 functions/classes 可以访问 private
和 protected
成员。
友元函数不是 class 的成员函数,它被声明为友元函数,因此它没有隐式指针 this
所以在:
void x(Time h, Time m) {hours = h; minutes = m;} // doesn't compile
因为只要 hours
和 minutes
是 class Time
类型对象的数据成员,您就需要通过 class.
假设您的 class
Time
有一个名为setMinutes()
的成员函数,其定义为:int Times::SetMinutes(int h, int m) { hours = h; // in fact it is translated as: this->hours = h; this->minutes = m; }
您可能已经看到插入运算符
<<
被 class 以这种方式重载: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; }
另外
+
运算符的声明不正确:friend Time operator+(const Time & t);
因为+
是一个二元运算符所以它需要两个操作数"lhs"和"rhs"所以你可以:
friend Time operator+(const Time & lsh, const Time& rhs);
或者:
Time operator+(const Time & t); // OK
第二个版本有效,因为
+
是一个成员函数:这意味着它通过取消引用 [=] 使用运算符调用的对象作为 "lhs" 19=] 和参数t
为 "rhs".首选版本是
friend
。