为什么要使用友方功能

时间:2015-11-17 04:25:55

标签: c++ friend

我正在尝试重载运算符'='和运算符'<<'用同样的方法。

class Vect{
 public:
  //..
   Vect& operator=(const Vect& a);      
   ostream& operator<<(ostream& out, const Vect& vect);
  //..
 private:
  int *data;
  int size;
};

这项工作

Vect& Vect:: operator=(const Vect& a){
 //.. 
 //copy data operator
 for(int i = 0; i< size; i++){
  data[i] = a.data[i];
 }
 return *this;
}

但是:此代码导致错误
[错误]'std :: ostream&amp; Vect :: operator&lt;&lt;(std :: ostream&amp;,const Vect&amp;)'必须只有一个参数

ostream& Vect::operator<<(ostream& out, const Vect& vect){
 //.. print vect
}

我正在阅读“C ++中的数据结构和算法”一书(1.5.4)。 他们说我必须使用班级朋友来重载'&lt;&lt;&lt;运营商,因为它访问私人会员数据。  我不明白为什么。重载'='运算符我也可以访问私有成员数据,而无需使用“朋友”。

2 个答案:

答案 0 :(得分:3)

当你在类定义中放入一个函数声明时,它默认成为一个成员函数,所以......

class Vect {
  public:
    ostream& operator<<(ostream& out, const Vect& vect);
};

...因为它请求创建一个带有太多参数参数的<<函数而不会编译:任何成员函数operator<<都应该使用*this作为&#34;左手边&#34;争论,并采取另一个论点为&#34;右手边&#34;。

您有两种选择:

  • 将上面的内容替换为friend ostream& operator<<(ostream& out, const Vect& vect);,它告诉编译器该函数是周围类的朋友,但不是其成员。作为非成员,它所操作的两个参数是outvect - 不涉及*this个对象。一切正常,作为friend定义也可以访问vect中的私有和受保护的成员数据。

  • operator<<声明移到class Vect定义之外;这也使它成为非会员功能,但并不使其成为朋友。

答案 1 :(得分:2)

  

重载'='运算符我也可以访问私有成员数据而不使用“朋友”

operator=被声明为成员函数,可以访问私有成员。

  

他们说我必须使用班级朋友来重载'&lt;&lt;&lt;运算符,因为它是访问私有成员数据。我不明白为什么。

问题是您将operator<<声明为成员函数,应将其声明为非成员函数。这就是你得到错误的原因。

operator<<应该是非成员函数,因为当声明为成员函数时,它需要一个不同的类型作为其左手参数,即std::ostream&,而不是Vect&

这意味着,作为非成员函数,operator<<无法访问该类的私有成员,除非您将其声明为朋友,例如:

class Vect {
public:
  //..
    friend ostream& operator<<(ostream& out, const Vect& vect);
  //..

请注意,上面的语法使operator<<成为非成员函数。