オーバーロードオペレーター<<はクラス内で動作しますか?
-
27-10-2019 - |
質問
つまり、私はクラス内のオペレーター<<を過負荷にしようとしていました
このような
class A {
public:
ostream &operator<<(ostream &os);// which doesnt work
private:
friend ostream &operator<<(ostream &os, const A& a); //Works
int i;
};
Definition
ostream &operator<<(ostream &os, const A& a) {
os<<a.i;
return os;
}
クラスに固有のクラス内でオペレーターをオーバーロードできないのはなぜですか?それとも私は何かが足りませんか?それとも、私はそのような方法で考えることさえ愚かですか?お知らせ下さい。
解決
メンバー関数:
ostream &operator<<(ostream &os);
します 仕事ですが、あなたが望む状況のためではありません。あなたが次のようなことをするとき、それは呼び出されます:
A a;
a << std::cout;
つまり、オブジェクトは演算子の左側です。
他のヒント
問題はあなたのことです operator<<
かかるだろう ostream
2番目のパラメーターとして、最初のパラメーターではありません。そうすれば、できます myObject << std::cout
, 、しかし、それは直感的ではないように見え、あなたは通話をチェーンすることができないでしょう operator<<
左結合であること。
メンバー関数とは対照的に、オペレーターを友人として宣言することのもう1つの利点は、自動変換が発生する可能性があることです。つまり、クラスがある場合 B
それは派生していません A
しかし、 B(A const&)
コンストラクター、あなたはまだできるでしょう std::cout << my_b;
そして、それをanに変換します A
そして、印刷しました。
幸いなことに、定義 operator<<
あなたが望むなら、友人はクラス内で行うことができます。あなたのコードは次のように書くことができます
class A {
int i;
friend std::ostream& operator<<(std::ostream& o, A const& a) {
o << a.i;
return o;
}
};
なぜ標準では、引数がどの側に進むべきかを指定することができないのはなぜですか?それがしたふりをして、追加しましょう left_of
と right_of
指定するキーワード:
struct B;
struct A {
A left_of operator+(B const&) {
return *this;
}
};
struct B {
B right_of operator+(A const&) {
return *this;
}
};
私たちがそうするとき、今何が起こるか A a; B b; f(a + b);
?各クラスには、このケースを処理するオペレーターがあります。つまり、決定できません。とにかく回心の可能性のために多くのオペレーターが友達になるべきであると見ると、この種のことを許可しないことはそれほど大きな問題ではなく、この種の曖昧さを防ぎます。 (もちろん、メンバーオペレーターと無料のオペレーターを定義することもできます。これにより、非常によく似た問題が発生します。)
ちなみに、物事はそうであるように、あなたの定義 friend operator<<
何も返さず、チェーンが台無しになります。
クラスの最初の引数の非静的なメンバー関数は、このポインターであることを忘れないでください。したがって、「オペレーター<<」関数の署名は、編集後:
ostream &operator<<(A *this, ostream &os);
これは、次のようなことをするときに機能します。
A obj;
obj << std::cout;
「OBJ」を最初の引数と、「std :: cout」をオペレーター「<<」に対する2番目の引数と考えてください。
「<<」を過負荷するためのより良い方法は、この方法で過負荷のオペレーターを連想させることができるため、友人機能を使用することです。