C ++ - ostream, friends and namespaces

Everything was fine until I moved the objects to the namespace. And now the compiler claims that my color attributes are private.

I thought that all friends should share the encapsulated information with those who are friends with the class.

Color.h

friend ostream & operator << (ostream& output, const st::Color& 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; } 

Mistake:

 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) ===| 

So what is the deal? I am using Code :: Blocks as an IDE. And it won't even show any properties or methods when I use the dot operator in the color parameter. This is obviously a sign that something is wrong ... somewhere.

I overloaded the friend statement, and it just compiles. No error elsewhere. What gives?

It is declared as follows:

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

Edit:

In my CPP, I just did this:

 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 } 

There are no compilation errors, but is it normal for such a situation to use the namespace in the header again? Or is it completely from what I should do?

Edit: @Rob thanks for your input!

+7
source share
2 answers

You need to declare and define your statements in the same namespace as the object. They will still be found through a search for dependent arguments.

A typical implementation would look like this:

 /// 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; } 

Edit

It seems that you are not declaring your operator<< in the namespace and also defining it outside the namespace. I have adjusted the code.

+5
source

You also need to qualify your operator in the namespace. This is a function signature declared in a namespace, so you need a prefix namespace to access its symbol.

Try the following:

 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; } } 
0
source

All Articles