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

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

问题描述

在我正在开发的项目中,我有一个 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 :: 函数声明在score.cpp(有效地不声明它作为成员)。

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?

感谢您的时间!

EDIT

我删除了对头文件的重载的所有提及...但我得到以下(和唯一)错误。 binary'<<':没有操作符,它接受类型为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)

下面是完整的score.h

Below is the full score.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


推荐答案

您可能需要查看运算符重载常见问题

二进制运算符可以是左边参数的类或自由函数的成员。 (有些运算符,如赋值,必须是成员。)由于流运算符的左侧参数是一个流,流运算符必须是流类或自由函数的成员。对任何类型实现运算符<< 的规范方法是:

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;
}

请注意 / strong>一个成员函数。还要注意,它需要对象流$ 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;
}

或让操作员a 朋友

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;运算符重载:为类重载运算符的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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