0

したがって、クラスAとクラスBがあり、クラスBはクラスAを拡張します。両方のクラスで<<と>>をオーバーロードする必要があります。クラスBの演算子の関数定義で、クラスAからオーバーロードされた演算子を呼び出せることを期待していましたが、問題が発生しました。

#include <iostream>
#include <string>
using namespace std;

class A {
friend ostream& operator<<(ostream& out, A a);
protected:
    int i;
    string st;
public:
    A(){
        i=50;
        st = "boop1";
    }
};

ostream& operator<<(ostream &out, A a) {
out << a.i << a.st;
return out;
}

class B : public A {
friend ostream& operator<<(ostream& out, B b);
private:
    int r;
public:
    B() : A() {
        r=12;
    }
};

ostream& operator<<(ostream &out, B b) {
out = A::operator<<(out, b);    //operator<< is not a member of A
out << "boop2" << b.r;
return out;
}

int main () {
B b;
cout << b;
}

Aのバージョンのoperator<<をBのバージョンのoperator<<で呼び出そうとしましたが、もちろん実際にはAに属していないため、コンパイルできません。これをどのように達成する必要がありますか?

また、実際にはAとBには独自のヘッダーファイルと本文ファイルがあることに注意してください。

4

3 に答える 3

3

Bオブジェクトをオブジェクトのように見せることができAます。

std::ostream& operator<< (std::ostream& out, B const& b) {
    out << static_cast<A const&>(b);
    out << "boop2" << b.r;
    return out;
}

ほぼ確実に、値で出力されるオブジェクトを渡したくないことに注意してください。代わりに使用するように署名を変更しましたconst&。これは、オブジェクトが変更されず、コピーされないことを示します。

于 2012-09-21T00:06:34.467 に答える
2

Aoperator<<は確かにのメンバーではなくA、名前空間スコープにあります。ここでの正しいアプローチは、型強制を使用して過負荷解決が正しいことを実行できるようにすることです。変化する:

out = A::operator<<(out, b);

に:

out << static_cast<A>(b);

また、演算子を変更して2番目の引数をで取る必要const&があります。この場合、余分なコピーを避けるために次のようにする必要があります。

out << static_cast<A const&>(b);
于 2012-09-21T00:06:17.160 に答える
0

これらはグローバル関数であり、スコープ解決演算子で修飾しないでください。

operator<<(out, static_cast<const A&>(b)) << "boop2" << b.r;

現在の関数を呼び出さず、無限再帰を取得しないように、キャストする必要があります。operator<<また、の結果をout;に割り当てないでください。それは機能せず、あなたがやりたいことではありません。

また、関数はconst A&'sとconst B&'sを受け入れる必要があります(つまり、const値ではなく参照によってパラメーターを受け入れる必要があります)。これにより、不要なコピーを防ぐことができます。

于 2012-09-21T00:06:28.173 に答える