問題描述
在我正在處理的一個項目中,我有一個 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;
}
這篇關于'朋友'功能和<<運算符重載:為類重載運算符的正確方法是什么?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!