在将对象移动到命名空间之前,一切都很好。现在编译器声称我的Color属性是私有的。
我认为朋友的全部意义是与那些阶级朋友分享封装信息。
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;
}
错误:
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) ===|
那么交易是什么? 我正在使用Code :: Blocks作为我的IDE。当我在“color”参数上使用点运算符时,它甚至不会显示任何属性或方法。这显然是出现问题的迹象......某处。
我把朋友操作员超载了,它编译得很好。别处没有错误。 是什么给了什么?
声明如下:
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感谢您的投入!
答案 0 :(得分:8)
您还需要在与对象相同的命名空间中声明和定义运算符。它们仍将通过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<<
并且还在命名空间之外定义它。我调整了代码。
答案 1 :(得分: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;
}
}