c++ friend 遇到 namespace 无法访问 private 成员的问题

相关的文章(比较有意思,记录一下):http://www.cnblogs.com/lx20030303/archive/2012/09/21/2696258.html

先看例子。如下。

尝试编译的话,错误提示:

Entrance.cpp
srcEntrance.cpp(15) : error C2248: “lqr::Entrance::id”: 无法访问 private 成员
(在“lqr::Entrance”类中声明)
C:UsersAdministratorDesktop mpincludeEntrance.h(11) : 参见“lqr::E
ntrance::id”的声明
C:UsersAdministratorDesktop mpincludeEntrance.h(9) : 参见“lqr::En
trance”的声明
srcEntrance.cpp(15) : error C2248: “lqr::Entrance::number”: 无法访问 private
成员(在“lqr::Entrance”类中声明)
C:UsersAdministratorDesktop mpincludeEntrance.h(10) : 参见“lqr::E
ntrance::number”的声明
C:UsersAdministratorDesktop mpincludeEntrance.h(9) : 参见“lqr::En
trance”的声明
NMAKE : fatal error U1077: “"D:Program Files (x86)Microsoft Visual Studio 12.
0VCBINcl.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	est.exe: bin obj objmain.obj objEntrance.obj
    $(LINK) $(L_DEBUG) $(L_OUT)bin	est.exe objmain.obj objEntrance.obj

objmain.obj: srcmain.cpp includeEntrance.h
    $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) srcmain.cpp $(C_OUT)objmain.obj

objEntrance.obj: srcEntrance.cpp includeEntrance.h
    $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) srcEntrance.cpp $(C_OUT)objEntrance.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
原文地址:https://www.cnblogs.com/qrlozte/p/4234498.html