【QIUC】第一卷-CC++高级(十三)- 友元函数是某个类的成员时出现的问题
这里主要是头文件的包含问题以及各个文件中类的使用问题
源码
//Computer.h
#pragma once
#include <string>
#include "ComputerService.h"
class ComputerService;
class Computer
{
public:
Computer();
std::string description();
private:
std::string cpu;
friend void ComputerService::upgrade(Computer* computer);
};
//Computer.cpp
#include "Computer.h"
#include <sstream>
Computer::Computer()
{
this->cpu = "i7";
}
std::string Computer::description()
{
std::stringstream ret;
ret << cpu;
return ret.str();
}
//ComputerService.h
#pragma once
#include "Computer.h"
class Computer;
class ComputerService
{
public:
void upgrade(Computer* com);
};
//ComputerService.cpp
#include "ComputerService.h"
#include "Computer.h"
class Computer;
void ComputerService::upgrade(Computer* com)
{
com->cpu = "i9";
}
问题
即使声明友元函数,在该友元函数内依旧无法访问类的私有数据成员
解决
-
注意在Computer.h中,由于声明了友元函数friend void ComputerService::upgrade(Computer* computer)
#include "ComputerService.h"为了要让编译器获得类的完整定义,知道里面的成员函数,也就包括 upgrade函数和类内的私有成员,如cpu等,如果不加,会提示错误信息:不允许指针指向不完整的类类型
class ComputerService 为了让编译器知道ComputerService是一个类。
-
在ComputerService.h中
class Computer 是为了使编译器知道**void upgrade(Computer* com)**中的参数是合法的
到此也就结束,但是若再加上**#include "Computer.h"而Computer.h 中有包含了ComputerService.h 类,这样就出现了交叉编译也就是一个鸡和蛋的问题,导致编译器在编译时出现这样的情况:即使在这个Computer类中我们声明ComputerService::upgrade** 函数为友元后,编译器并没有把它当作友元函数处理,报不能访问私有成员的错误。