【原】运算符重载与名字空间的困惑

【原】运算符重载与名字空间的困惑

   学习数据结构,用到了输入输出运算符重载,结果编译之下,错误重重,,随即停止学习进度,追查祸源,在花费巨大脑力与时间成本之后,终于知自己错误之所在,定位于名字空间之困扰。为牢记教训,写一简化版本记录 debug 过程如下,警示自己。

问题:
   

   有如下两个代码文件:
   // 20060816_operator.cxx

 1  #include  < iostream >
 2  using   namespace  std;
 3  #include  " 20060816_operator.h "
 4  int  main( int  argc,  char *  argv[])
 5  {
 6       const  std:: string  GHH( " GuoHonghua " );
 7      Honghua ghh(GHH);
 8      cout  <<  ghh  <<  endl;
 9       return   0 ;
10  }
   

// 20060816_operator.h

 1  #ifndef _20060816_OPERATOR_GHH_
 2  #define  _20060816_OPERATOR_GHH_    1
 3 
 4  //  Author : GuoHonghua
 5  //  Date : 2006.08.16
 6  //  File : 20060816_operator.h
 7 
 8  #include  < iostream >
 9  #include  < string >
10  class  Honghua
11  {
12      friend std::ostream &   operator << (std::ostream &  os,  const  Honghua &  ghh);
13  public :
14      Honghua( const  std:: string &  ghh) : _ghh(ghh)
15      {
16      }
17 
18  private :
19      std:: string  _ghh;
20  };
21 
22  std::ostream &   operator << (std::ostream &  os,  const  Honghua &  ghh)
23  {
24      os  <<  ghh._ghh;
25       return  os;
26  }
27 
28  #endif   //  end of _20060816_OPERATOR_GHH_

用上面两个文件建立工程,vc6.0下编译会出错。报告如下:

--------------------Configuration: 20060816_operator - Win32 Debug--------------------

Compiling...

20060816_operator.cxx

f:\ghh_project\cxxdetail\20060816_operator.h(24) : error C2248: '_ghh' : cannot access private member declared in class 'Honghua'

        f:\ghh_project\cxxdetail\20060816_operator.h(19) : see declaration of '_ghh'

F:\ghh_project\CxxDetail\20060816_operator.cxx(8) : error C2593: 'operator <<' is ambiguous

Error executing cl.exe.

 

20060816_operator.exe - 2 error(s), 0 warning(s)
解决:
   

1.  调整名字空间声明和自定义头文件的次序,如下:

1  #include  < iostream >
2  #include  " 20060816_operator.h "
3  using   namespace  std;
4  int  main( int  argc,  char *  argv[])
5 

2.  把类定义于标准名字之内,20060816_operator.h文件修改如下(不推荐)

 1  #ifndef _20060816_OPERATOR_GHH_
 2  #define  _20060816_OPERATOR_GHH_    1
 3 
 4  //  Author : GuoHonghua
 5  //  Date : 2006.08.16
 6  //  File : 20060816_operator.h
 7 
 8  #include  < iostream >
 9  #include  < string >
10  namespace  std
11  {
12       class  Honghua
13      {
14          friend std::ostream &   operator << (std::ostream &  os,  const  Honghua &  ghh);
15       public :
16          Honghua( const  std:: string &  ghh) : _ghh(ghh)
17          {
18          }
19          
20       private :
21          std:: string  _ghh;
22      };
23      
24      
25      std::ostream &   operator << (std::ostream &  os,  const  Honghua &  ghh)
26      {
27          os  <<  ghh._ghh;
28           return  os;
29      }
30  }
31  #endif   //  end of _20060816_OPERATOR_GHH_ 

3.  使用头文件iostream.h代替iostream,比较落后的方式(不推荐!

 1  //  20060816_operator.cxx
 2  //  #include <iostream>
 3  #include  < iostream.h >
 4  #include  < iostream.h >
 5  #include  " 20060816_operator.h "
 6  int  main( int  argc,  char *  argv[])
 7  {
 8       const  std:: string  GHH( " GuoHonghua " );
 9      Honghua ghh(GHH);
10      cout  <<  ghh  <<  endl;
11       return   0 ;
12  } 

 1  //  20060816_operator.h
 2  #ifndef _20060816_OPERATOR_GHH_
 3  #define  _20060816_OPERATOR_GHH_    1
 4 
 5  //  Author : GuoHonghua
 6  //  Date : 2006.08.16
 7  //  File : 20060816_operator.h
 8  //  #include <iostream>
 9  #include  < iostream.h >
10  #include  < string >
11 
12  class  Honghua
13  {
14      friend ostream &   operator << (ostream &  os,  const  Honghua &  ghh);
15  public :
16      Honghua( const  std:: string &  ghh) : _ghh(ghh)
17      {
18      }
19      
20  private :
21      std:: string  _ghh;
22  };
23 
24 
25  ostream &   operator << (ostream &  os,  const  Honghua &  ghh)
26  {
27      os  <<  ghh._ghh;
28       return  os;
29  }
30 
31  #endif   //  end of _20060816_OPERATOR_GHH_

4.  任何时候都不使用using namespace 声明!这是只需要修改20060816_operator.cxx文件如下:

 1  #include  < iostream >
 2  #include  " 20060816_operator.h "
 3  int  main( int  argc,  char *  argv[])
 4  {
 5       //  const string GHH("GuoHonghua");
 6       const  std:: string  GHH( " GuoHonghua " );
 7      Honghua ghh(GHH);
 8       //  cout << ghh << endl;
 9      std::cout  <<  ghh  <<  std::endl;
10       return   0 ;
11  }

体会:
   名字空间本来就是为了解决名字冲突问题而引入,以使标准库不受外界影响。在这个意义上来说,
using namespace std;不是可以随意使用的语句,应该考虑到它的位置对程序的可能影响,而最彻底的杜绝错误的解决办法是在任何时候任何情况下都不使用此语句!

你可能感兴趣的:(【原】运算符重载与名字空间的困惑)