Everything was fine until I moved my objects to a namespace. And now the compiler claims that my Color attributes are private.
I thought the whole point of friends was to share encapsulated information with those a class befriends.
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;
}
error:
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'm using Code::Blocks as my IDE. And it won't even show any properties or methods when I use the dot operator on the "color" parameter. This is obviously a sign of something going wrong...somewhere.
I've taken the friend operator overloading out and it compiles just fine. No error elsewhere. What gives?
It's declared as follows:
namespace st{
class Color {
friend ostream & operator << (ostream& output, const st::Color& color);
public:
....
private:
.....
};
};
Edit:
In my CPP I've now done 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
}
No compile errors, but is it normal for such a situation to use the namespace again in the header? Or is this completely off from what I should be doing?
Edit: @Rob thanks for your input as well!
You need to declare and define your operators in the same namespace as the object as well. They will still be found through Argument-Dependent-Lookup.
A usual implementation will 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 declarin your operator<<
in the namespace and are also defining it outside of the namespace. I've adjusted the code.