"友達"の機能 << オペレーターの過負荷:何が正しい過負荷オペレーターのためのクラス?
-
26-09-2019 - |
質問
プロジェクトに感い Score
クラスは、以下のとおり定め score.h
.うことにより過負荷では、 <<
に対して演算を行ってい _points + " " + _name
は印刷済。
こちらは何にしようとして:
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回、実際に)
から受けることになってしまいれている宣言に過負荷を友人としての機能:
friend ostream & operator<< (ostream & os, Score right);
を削除す Score::
らの関数宣言score.cpp (効果的な宣言としているものです。
なぜこの作品は、元のコードの抜粋を参照しない?
りの時間!
編集
削除してしまいましたすべての言及の過負荷のヘッダファイル...なかで以下の(のみ)エラーになります。 binary '<<' : no operator found which takes a right-hand operand of type 'Score' (or there is no acceptable conversion)
このような試験は、main()であると同時に適切な過負荷?しらないのを含むエクスペディア)
以下の点です。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
解決
注意: するための オペレーターの過負荷のFAQ.
バイナリー事業者での左引数のクラスは無料です。(一部の事業者のように、必ず会員とする。) 以降、ストリームのオペレーターの左手の引数がストリームを、ストリーム事業者のいずれかしていくことができるストリームのクラスは無料です。の標準的な方法の実施 operator<<
のための任意の型です:
std::ostream& operator<<(std::ostream& os, const T& obj)
{
// stream obj's data into os
return os;
}
がありますのでご注意 ない 会員機能です。また、このオブジェクトストリーム当たり const
参考にする。ことになりたくないからコピーするオブジェクトのためのストリームで、またいと思っているストリーミングを変更します。
あるときにストリーム物体の内部にアクセスできないか、またはそのクラスの"公開インタフェースのオペレーターが取得できなくても生まれることを期待しています。しかし、二つの選択肢:置いてか公会員のクラスは、ストリーミング
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;
}
または、オペレーター、 friend
class T {
public:
friend std::ostream& operator<<(std::ostream&, const T&);
private:
int data_;
};
できるようにアクセスし、クラスのプライパーツ:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << obj.data_;
return os;
}
他のヒント
あなたが+
にScore
を追加することができますので、あなたがお互いに2つのint
オブジェクトを追加し、別のあなたがScore
にScore
を追加することができますので、第三ことができるようにあなたがint
ためにオペレータのオーバーロードを書きたかったとしましょう。 Score
は最初のパラメータであるものがスコアのメンバ関数であることができます。しかしint
が最初のパラメータである1は右、int
のメンバ関数になることができませんか?そのお手伝いをするには、無料の機能としてそれらを書き込むことができます。あなたが自由に関数を書くように、この<<
演算子で何が起こっているかである。つまり、あなたはostream
にメンバ関数を追加することはできません。それはあなたが離れてScore::
の一部を取るとき、それが何を意味するかだ。
さて、なぜそれがfriend
ことがありますか?それはしていません。あなただけのパブリックメソッド(getPoints
とscoreGetName
)を呼んでいます。彼らはプライベート変数に直接お話したいのでお友達事業者の多くを参照してください。彼らは書かれており、クラスをmaintaing者によって維持されているので、私は、それをすることにより、それは大丈夫です。ただ、メンバー関数-VS-フリー機能部分にまで混乱の友人の一部を得ることはありません。
あなたはoperator<<
は例のメンバ関数であるときは、最初のパラメータ(オブジェクトメソッドのは、上で呼び出されている)としてoperator<<
を取るScore
を作成し、それに余分なパラメータを与えているので、コンパイルエラーを取得しています終わります。
あなたはメンバ関数として宣言のバイナリ演算子を呼んでいるときは、式の左辺は、メソッドのは、上で呼び出されているオブジェクトです。例えばa + b
のかもしれないが、このように動作します:
A a;
B b
a.operator+(b)
それは(場合によっては非会員二項演算子を使用することが一般的に望ましいです - 例えばoperator<<
for ostream
それを行うための唯一の方法があり、その場合には、このようなa + b
のかもしれない作品ます:
A a;
B b
operator+(a, b);
ここでそれを行うの両方の方法を示す完全な例です。メイン()が出力されます '55' 3回:
#include <iostream>
struct B
{
B(int b) : value(b) {}
int value;
};
struct A
{
A(int a) : value(a) {}
int value;
int operator+(const B& b)
{
return this->value + b.value;
}
};
int operator+(const A& a, const B& b)
{
return a.value + b.value;
}
int main(int argc, char** argv)
{
A a(22);
B b(33);
std::cout << a + b << std::endl;
std::cout << operator+(a, b) << std::endl;
std::cout << a.operator+(b) << std::endl;
return 0;
}