C – ostream,朋友和命名空间

前端之家收集整理的这篇文章主要介绍了C – ostream,朋友和命名空间前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
一切都很好,直到我将对象移动到命名空间.现在编译器声称我的Color属性是私有的.

我认为朋友的全部意义是与那些阶级朋友分享封装信息.

Color.h

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

Color.cpp:

  1. ostream & operator <<(ostream& output,const st::Color& color) {
  2.  
  3. output << "Colors:\nalpha\t: " << color.a << "\nred\t: " << color.r << "\ngreen\t: " << color.g
  4. << "\nblue\t: " << color.b << "\nvalue\t: " << color.color();
  5.  
  6. return output;
  7. }

错误

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

那么这笔交易是什么?
我正在使用Code :: Blocks作为我的IDE.当我在“color”参数上使用点运算符时,它甚至不会显示任何属性方法.这显然是出现问题的迹象……某处.

我把朋友运算符超载了,它编译得很好.别处没有错误.
是什么赋予了?

它声明如下:

  1. namespace st{
  2.  
  3. class Color {
  4.  
  5. friend ostream & operator << (ostream& output,const st::Color& color);
  6. public:
  7. ....
  8. private:
  9. .....
  10.  
  11. };
  12. };

编辑:

在我的CPP中,我现在已经这样做了:

  1. namespace st{
  2. ostream & st::operator <<(ostream& output,const st::Color& color) {
  3.  
  4. output << "Colors:\nalpha\t: " << color.a << "\nred\t: " << color.r << "\ngreen\t: " << color.g
  5. << "\nblue\t: " << color.b << "\nvalue\t: " << color.color();
  6.  
  7. return output;
  8. }
  9. }
  10.  
  11. st::Color::Color() {
  12.  
  13. reset();
  14. }
  15.  
  16. st::Color::Color(const Color& orig) {
  17.  
  18. a = orig.a;
  19. r = orig.r;
  20. g = orig.g;
  21. b = orig.b;
  22. }
  23.  
  24. void st::Color::reset() {
  25. a = 0;
  26. r = 0;
  27. g = 0;
  28. b = 0;
  29. }
  30. ... etc
  31. }

没有编译错误,但这种情况在标题中再次使用命名空间是否正常?或者这完全取决于我应该做什么?

编辑:
@Rob感谢您的投入!

解决方法

您需要在与对象相同的命名空间中声明和定义运算符.它们仍将通过Argument-Dependent-Lookup找到.

通常的实现将如下所示:

  1. /// header file
  2. namespace foo {
  3. class A
  4. {
  5. public:
  6. A();
  7.  
  8. private:
  9. int x_;
  10. friend std::ostream& operator<<(std::ostream& o,const A& a);
  11. };
  12.  
  13. std::ostream& operator<<(std::ostream& o,const A& a);
  14. } // foo
  15.  
  16. // cpp file
  17. namespace foo {
  18. A::A() : x_(23) {}
  19.  
  20. std::ostream& operator<<(std::ostream& o,const A& a){
  21. return o << "A: " << a.x_;
  22. }
  23. } // foo
  24.  
  25.  
  26. int main()
  27. {
  28. foo::A a;
  29. std::cout << a << std::endl;
  30. return 0;
  31. }

编辑

您似乎没有声明您的操作符<<在命名空间中,也在命名空间之外定义它.我调整了代码.

猜你在找的C&C++相关文章