???學習數據結構,用到了輸入輸出運算符重載,結果編譯之下,錯誤重重,,隨即停止學習進度,追查禍源,在花費巨大腦力與時間成本之后,終于知自己錯誤之所在,定位于名字空間之困擾。為牢記教訓,寫一簡化版本記錄
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;不是可以隨意使用的語句,應該考慮到它的位置對程序的可能影響,而最徹底的杜絕錯誤的解決辦法是在任何時候任何情況下都不使用此語句!