c++ friend 遇到 namespace 无法访问 private 成员的问题
相关的文章(比较有意思,记录一下):http://www.cnblogs.com/lx20030303/archive/2012/09/21/2696258.html
先看例子。如下。
尝试编译的话,错误提示:
Entrance.cpp
src\Entrance.cpp(15) : error C2248: “lqr::Entrance::id”: 无法访问 private 成员
(在“lqr::Entrance”类中声明)
C:\Users\Administrator\Desktop\tmp\include\Entrance.h(11) : 参见“lqr::E
ntrance::id”的声明
C:\Users\Administrator\Desktop\tmp\include\Entrance.h(9) : 参见“lqr::En
trance”的声明
src\Entrance.cpp(15) : error C2248: “lqr::Entrance::number”: 无法访问 private
成员(在“lqr::Entrance”类中声明)
C:\Users\Administrator\Desktop\tmp\include\Entrance.h(10) : 参见“lqr::E
ntrance::number”的声明
C:\Users\Administrator\Desktop\tmp\include\Entrance.h(9) : 参见“lqr::En
trance”的声明
NMAKE : fatal error U1077: “"D:\Program Files (x86)\Microsoft Visual Studio 12.
0\VC\BIN\cl.EXE"”: 返回代码“0x2”
Stop.
解决办法:把Entrance.cpp的第13行改为ostream& lqr::operator<<(ostream& os, const Entrance& e)
Entrance.h
1 #ifndef ENTRANCE_H 2 #define ENTRANCE_H 3 4 #include <iostream> 5 6 namespace lqr { 7 8 class Entrance 9 { 10 unsigned int number; 11 int id; 12 public: 13 Entrance(unsigned int number, int id); 14 friend std::ostream& operator<<(std::ostream& os, const Entrance& e); 15 }; 16 17 } 18 19 #endif // ENTRANCE_H
Entrance.cpp
1 #include "Entrance.h" 2 #include <iostream> 3 4 using namespace lqr; 5 using namespace std; 6 7 Entrance::Entrance(unsigned int number_val, int id_val) 8 :number(number_val), id(id_val) 9 { 10 // do nothing 11 } 12 13 ostream& operator<<(ostream& os, const Entrance& e) 14 { 15 return os << "Entrance #"<< e.id << ": "<< e.number; 16 }
main.cpp
#include "Entrance.h" #include <iostream> using namespace std; using namespace lqr; int main() { Entrance en(99, 123); cout << en << endl; return 0; }
Makefile
# compiler CC = cl # linker LINK = link # libraries # headers HEADER_PATH = /I include # options EHSC = /EHsc COMPILATION_ONLY = /c C_OUT = /Fo: L_OUT = /OUT: # compiler & linker debug option, to disable debug, replace '/Zi' & '/DEBUG' with empty strings C_DEBUG = /Zi L_DEBUG = /DEBUG # C_DEBUG = # L_DEBUG = # targets bin\test.exe: bin obj obj\main.obj obj\Entrance.obj $(LINK) $(L_DEBUG) $(L_OUT)bin\test.exe obj\main.obj obj\Entrance.obj obj\main.obj: src\main.cpp include\Entrance.h $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) src\main.cpp $(C_OUT)obj\main.obj obj\Entrance.obj: src\Entrance.cpp include\Entrance.h $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) src\Entrance.cpp $(C_OUT)obj\Entrance.obj # folders obj: mkdir obj bin: mkdir bin # clean # bin, obj folders and pdb files .PHONY: clean clean: -rmdir /s /q bin -rmdir /s /q obj -del *.pdb