用于运算符重载的friend关键字

时间:2016-07-28 13:59:23

标签: c++

我试着为<< -operator-overloading写一个简单的例子。 之前,我从未使用过关键字“朋友”。但没有它它就行不通。我做了什么错误或为什么我需要朋友关键字?

class rational{

public:
 rational(double num, double count)
    : n(num),c(count){}

 rational& operator+=(const rational& b){
    this->n+= b.n;
    this->c+= b.c;
    return *this;
 }

 friend std::ostream& operator<<(std::ostream& os, const rational& obj)
 {
 std::cout << obj.n << "," << obj.c << std::endl;
 return os;
 }

private:
 double n;
 double c;
};

由于

3 个答案:

答案 0 :(得分:3)

你没有犯任何错误。 friend关键字为您的operator<<()实施提供了private(以及protected(如果您有的话)成员的访问权限。

请注意,因为它是朋友,operator<<()这里隐式地是一个自由函数而不是成员函数(如果它是一个成员函数,它可以访问private的东西!)。因为它只在类中声明和定义,所以只能通过参数依赖查找找到它,但这对于operator<<来说很好,并且是一个你不必担心的细节。

答案 1 :(得分:2)

您在类中声明并定义运算符,因此没有friend它有一个隐式的rational类型的第一个操作数。如果您在课堂外宣布了操作员,那么您就不会遇到这样的问题,但是您将无法访问n和c。

答案 2 :(得分:2)

您希望流式传输内部无法通过其班级访问的对象&#39;公共接口,因此操作员无法获得它们。然后你有两个选择:将一个公共成员放入进行流式传输的类

class T {
  public:
    void stream_to(std::ostream& os) const {os << obj.data_;}
  private:
    int data_;
};

并从运营商那里打电话:

inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
   obj.stream_to(os);
   return os;
}

或让运营商成为friend

class T {
  public:
    friend std::ostream& operator<<(std::ostream&, const T&);
  private:
    int data_;
};

以便它可以访问班级&#39;私人部分:

inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
   os << obj.data_;
   return os;
}