11

オブジェクトを名前空間に移動するまでは、すべて問題ありませんでした。そして今、コンパイラは、私の Color 属性が非公開であると主張しています。

友達の要点は、カプセル化された情報をクラスの友達と共有することだと思いました。

カラー.h

friend ostream & operator << (ostream& output, const st::Color& color);

カラー.cpp:

 ostream & operator <<(ostream& output, const st::Color& color) {

    output << "Colors:\nalpha\t: " << color.a << "\nred\t: "  << color.r << "\ngreen\t: " << color.g
            << "\nblue\t: " << color.b <<  "\nvalue\t: " << color.color();

    return output;
}

エラー:

Color.h||In function 'std::ostream& operator<<(std::ostream&, const st::Color&)':|
Color.h|52|error: 'unsigned char st::Color::a' is private|
Color.cpp|15|error: within this context|
Color.h|49|error: 'unsigned char st::Color::r' is private|
Color.cpp|15|error: within this context|
Color.h|51|error: 'unsigned char st::Color::g' is private|
Color.cpp|15|error: within this context|
Color.h|50|error: 'unsigned char st::Color::b' is private|
Color.cpp|16|error: within this context|
||=== Build finished: 8 errors, 0 warnings (0 minutes, 1 seconds) ===|

それで、取引は何ですか?IDE として Code::Blocks を使用しています。また、「色」パラメーターでドット演算子を使用すると、プロパティやメソッドも表示されません。これは明らかに何かがうまくいかない兆候です...どこかで。

友人の演算子のオーバーロードを取り除いたところ、問題なくコンパイルされました。他にエラーはありません。何を与える?

次のように宣言されています。

namespace st{

class Color {

    friend ostream & operator << (ostream& output, const st::Color& color);
 public:
     ....
 private:
    .....

};
};

編集:

私のCPPでは、これを行いました:

namespace st{
ostream & st::operator <<(ostream& output, const st::Color& color) {

    output << "Colors:\nalpha\t: " << color.a << "\nred\t: "  << color.r << "\ngreen\t: " << color.g
            << "\nblue\t: " << color.b <<  "\nvalue\t: " << color.color();

    return output;
}
}

st::Color::Color() {

    reset();
}

st::Color::Color(const Color& orig) {

    a = orig.a;
    r = orig.r;
    g = orig.g;
    b = orig.b;
}

void st::Color::reset() {
    a = 0;
    r = 0;
    g = 0;
    b = 0;
}
... etc
}

コンパイルエラーはありませんが、このような状況でヘッダーで名前空間を再度使用するのは正常ですか? それとも、これは私がやるべきことから完全に外れていますか?

編集: @Rob もご意見をお寄せいただきありがとうございます。

4

2 に答える 2

10

オブジェクトと同じ名前空間で演算子を宣言および定義する必要もあります。これらは引き続き Argument-Dependent-Lookup によって検出されます。

通常の実装は次のようになります。

/// header file
namespace foo {
   class A
   {
    public:
    A();

    private:
    int x_;
    friend std::ostream& operator<<(std::ostream& o, const A& a);
    };

    std::ostream& operator<<(std::ostream& o, const A& a);
} // foo

// cpp file
namespace foo {
     A::A() : x_(23) {}

     std::ostream& operator<<(std::ostream& o, const A& a){
     return o << "A: " << a.x_;
    }
} // foo


int main()
{
  foo::A a;
  std::cout << a << std::endl;
  return 0;
}

編集

名前空間で自分を宣言しておらずoperator<<、名前空間の外でも定義しているようです。コードを調整しました。

于 2012-05-01T22:34:37.627 に答える
0

オペレーターも名前空間で修飾する必要があります。これは名前空間で宣言された関数シグネチャであるため、そのシンボルにアクセスするには、名前空間を前に付ける必要があります。

次のようにしてみてください。

namespace st {

    ostream & operator <<(ostream& output, const Color & color) {

        output << "Colors:\nalpha\t: " << color.a
               << "\nred\t: "   << color.r 
               << "\ngreen\t: " << color.g
               << "\nblue\t: "  << color.b
               << "\nvalue\t: " << color.color();

        return output;
    }
}
于 2012-05-01T22:49:56.583 に答える