'朋友'功能和<<运算符重载:为类重载运算符的正确方法是什么? [英] 'friend' functions and << operator overloading: What is the proper way to overload an operator for a class?

查看:33
本文介绍了'朋友'功能和<<运算符重载:为类重载运算符的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我正在处理的一个项目中,我有一个 Score 类,在下面的 score.h 中定义.我试图重载它,所以当对它执行 << 操作时,会打印 _points + " " + _name .

In a project I'm working on, I have a Score class, defined below in score.h. I am trying to overload it so, when a << operation is performed on it, _points + " " + _name is printed.

这是我尝试做的:

ostream & Score::operator<< (ostream & os, Score right)
{
    os << right.getPoints() << " " << right.scoreGetName();
    return os;
}

以下是返回的错误:

score.h(30) : error C2804: binary 'operator <<' has too many parameters

(这个错误实际上出现了4次)

(This error appears 4 times, actually)

我设法通过将重载声明为友元函数来使其工作:

I managed to get it working by declaring the overload as a friend function:

friend ostream & operator<< (ostream & os, Score right);

并从 score.cpp 中的函数声明中删除 Score::(实际上并未将其声明为成员).

And removing the Score:: from the function declaration in score.cpp (effectively not declaring it as a member).

为什么这行得通,而前一段代码却行不通?

Why does this work, yet the former piece of code doesn't?

感谢您的时间!

编辑

我删除了头文件中所有对重载的提及...但我收到以下(也是唯一的)错误.二进制'<<': 没有找到使用Score"类型的右侧操作数的运算符(或者没有可接受的转换)为什么我的测试在 main() 中找不到合适的重载?(这不是包含,我检查过)

I deleted all mentions to the overload on the header file... yet I get the following (and only) error. binary '<<' : no operator found which takes a right-hand operand of type 'Score' (or there is no acceptable conversion) How come my test, in main(), can't find the appropriate overload? (it's not the includes, I checked)

以下是完整的分数.h

#ifndef SCORE_H_
#define SCORE_H_

#include <string>
#include <iostream>
#include <iostream>

using std::string;
using std::ostream;

class Score
{

public:
    Score(string name);
    Score();
    virtual ~Score();
    void addPoints(int n);
    string scoreGetName() const;
    int getPoints() const;
    void scoreSetName(string name);
    bool operator>(const Score right) const;

private:
    string _name;
    int _points;

};
#endif

推荐答案

注意:您可能想查看 运算符重载常见问题解答.

二元运算符可以是其左侧参数类的成员,也可以是自由函数.(某些运算符,如赋值,必须是成员.)由于流运算符的左侧参数是一个流,因此流运算符要么必须是流类的成员,要么是自由函数.为任何类型实现 operator<< 的规范方法是:

Binary operators can either be members of their left-hand argument's class or free functions. (Some operators, like assignment, must be members.) Since the stream operators' left-hand argument is a stream, stream operators either have to be members of the stream class or free functions. The canonical way to implement operator<< for any type is this:

std::ostream& operator<<(std::ostream& os, const T& obj)
{
   // stream obj's data into os
   return os;
}

注意它不是一个成员函数.另请注意,它需要对象按 const 引用进行流式处理.那是因为您不想复制对象以流式传输它,并且您也不希望流式传输更改它.

Note that it is not a member function. Also note that it takes the object to stream per const reference. That's because you don't want to copy the object in order to stream it and you don't want the streaming to alter it either.

有时您希望流式传输内部无法通过其类的公共接口访问的对象,因此操作员无法获取它们.那么你有两个选择:要么将一个公共成员放入进行流式传输的类中

Sometimes you want to stream objects whose internals are not accessible through their class' public interface, so the operator can't get at them. Then you have two choices: Either put a public member into the class which does the streaming

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

并从操作员那里调用:

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

或者让操作员成为朋友

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

以便它可以访问类的私有部分:

so that it can access the class' private parts:

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

这篇关于'朋友'功能和&lt;&lt;运算符重载:为类重载运算符的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆