[关闭]
@coolwyj 2014-12-05T11:44:23.000000Z 字数 1089 阅读 2502

C++友元函数

C++


参考:百度百科


概念

友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。类授予它的友元特别的访问权。


注意事项

假设f是想正确声明的函数,c是和它相关的类:

  • 友元函数不是类的成员函数,所以友元函数的实现和普通函数一样,在实现时不用"::"指示属于哪个类,只有成员函数才使用"::"作用域符号
  • 类与类之间的友元关系不能继承。
  • 虚函数必须是成员函数。如果f必须是虚函数,就让它成为c的成员函数。
  • operator>>operator<<决不能是成员函数。如果f是operator>>或operator<<,让f成为非成员函数。如果f还需要访问c的非公有成员,让f成为c的友元函数。
  • 只有非成员函数对最左边的参数进行类型转换。如果f需要对最左边的参数进行类型转换,让f成为非成员函数。如果f还需要访问c的非公有成员,让f成为c的友元函数。
  • 其它情况下都声明为成员函数。如果以上情况都不是,让f成为c的成员函数。

对于第三点有如下例子:

  1. class rational {
  2. public:
  3. rational(int numerator = 0,int denominator = 1){}
  4. int numerator() const;
  5. int denominator() const;
  6. const rational operator*(const rational& rhs) const;
  7. private:
  8. ...
  9. };

可以很容易地对有理数进行乘法操作:
rational oneeighth(1,8);
rational onehalf(1,2);
rational result = onehalf * oneeighth; // 运行良好
result = result * oneeighth; // 运行良好

但不要满足,还要支持混合类型操作,比如,rational要能和int相乘。但当写下下面的代码时,只有一半工作:
result = onehalf * 2; // 运行良好
result = 2 * onehalf; // 出错!
第一个成功是因为编译器对2进行了隐式类型转换。如果构造函数声明为explicit,那么这个也是错的。
第二个错误是因为没有参数为int和rational的类运算符*

改为全局声明即可:

  1. const rational operator*(const rational& lhs,const rational& rhs){
  2. return rational(lhs.numerator() * rhs.numerator(),
  3. lhs.denominator() * rhs.denominator());
  4. }

但是此函数不需要声明为rational类的友元函数。因为不需要访问其私有成员。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注