写这篇文章的原因(前提):
网上只有在一个文件(声明和定义在同一个文档)里的解决方法,而分文件的方法却少见。在自己摸索了一下之后,决定分享给大家。
【大修了一次,改了很多】
分文件/在同一个文件里编写时,可能遇上的问题:
代码如下:
#include<iostream>
using namespace std;
class B;
class A{
private:
void test_friend(B b);
};
class B{
friend void A::test_friend(B b);
private:
int id;
};
void A::test_friend(B b){
cout<< b.id;
}
问题:报错
error: 'void A::test_friend(B)' is private within this context
原因:将非公有(即不可见)成员函数设为友元
更准确地说是,编译器在查找名字的时候只会查找定义之前的作用域内可见的名字。所以当函数是非公有的时候,编译器找不到这个函数。因为编译器可以推断错误原因,所以给出了以上报错提示。
所以无论分不分文件编写,成员函数都必须保证是可见的。
同一个文件编写方法:
可以看这篇文章(因为写的人比较多,没有筛查原作者,如果有,请告知,谢谢。
(13条消息) 把类的成员函数声明为友元函数,但不能访问私有成员的原因和解决办法_秃草是真的的博客-CSDN博客
要点:
1、将作为友元函数的类先声明(友元的那个成员函数只声明!!!
2、超前引用后面声明的类
3、完成超前引用的类的实现
4、友元函数在最后实现
分文件编写方法:
A.h //第一种方法,将B类变为友元类
#ifndef A_H
#define A_H
using namespace std;
class B;
class A
{
public:
A();
virtual ~A();
void test_firend(B b);
};
#endif // A_H
fish.h //第二种方法,将成员函数变成public
#include<iostream>
using namespace std;
class game;
class fish
{
public:
fish();
virtual ~fish();
void print1(game g);
protected:
private:
};
B.h
#ifndef B_H
#define B_H
#include"A.h"
class B
{
friend void A::test_firend(B b);
public:
B();
virtual ~B();
protected:
int id;
private:
};
#endif // B_H
A.cpp
#include "A.h"
#include"B.h"
#include<iostream>
A::A(){}
A::~A(){}
void A::test_firend(B b){
cout<<b.id<<endl;
cout<<"succeed to run function test_friend()"<<endl;
}
B.cpp
#include "B.h"
B::B(){}
B::~B(){}
成功编译!
在同一个文件的要点的基础上的补充(所以一定先看会同一个文件的编写方法)
要点:
1、声明友元friend的那个头文件要超前引用
2、两个头文件都要包含对方的头文件
3、两个的.cpp文件都分别要包含两个头文件
4、友元的那个成员函数对于声明友元的那个类,一定要是可见的(要么使成员函数是public,要么将声明友元的类变为成员函数的友元类)
最后:
1、在一个文件编写,友元函数可以是私有的,且不需要将另一个类作为有友元类,如果是代码简单,建议直接在一个文件里写。
2、【更新】将A类的成员函数声明为另一个类B类的友元时,B对于A的这个成员函数是可见的,但是A的成员函数并不被B可见。
如果有误,欢迎指出
如果需要引用该文章,请注明原出处!