为什么要使用好友功能

Why have to use friend function

本文关键字:好友 功能 为什么      更新时间:2023-10-16

我正在尝试重载运算符'='和运算符'<lt;'通过相同的方法。

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&Vect::运算符<lt;(std::ostream&,const Vect&)'必须只接受一个参数

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

我正在阅读"C++中的数据结构和算法"一书的第1.5.4部分。他们说我必须使用班级好友来超载<'运算符,因为它是访问私有成员数据。我不明白为什么。重载'='运算符i也可以在不使用"friend"的情况下访问私人成员数据。

当您将函数声明放入类定义中时,默认情况下它将成为成员函数,因此…

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

不会编译,因为它请求创建一个使用过多参数参数的<<函数:任何成员函数operator<<都应该使用*this作为"左手边"参数,并将另一个参数作为"右手边"参数。

你有两个选择:

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

  • operator<<声明移动到class Vect定义之外;这也使它成为一个非成员函数,但并不能使它成为朋友。

重载'='operator i也访问私人成员数据,而不使用"朋友"

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

他们说我必须使用班级好友来超载<'运算符,因为它正在访问私有成员数据。我不明白为什么。

问题是您将operator<<声明为成员函数,而它应该声明为非成员函数。这就是你出错的原因。

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

这意味着,作为一个非成员函数,operator<<不能访问类的私有成员,除非您将其声明为友元,例如:

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

注意,上面的语法使operator<<现在成为一个非成员函数。