将成员函数作为友元函数时,如何分文件编写

写这篇文章的原因(前提):

网上只有在一个文件(声明和定义在同一个文档)里的解决方法,而分文件的方法却少见。在自己摸索了一下之后,决定分享给大家。


【大修了一次,改了很多】 

分文件/在同一个文件里编写时,可能遇上的问题:

代码如下:

#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可见。

           如果有误,欢迎指出

           如果需要引用该文章,请注明原出处!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,为您提供具体的代码实现。 首先,我们需要定义一个复数类来存储复数的实部和虚部,示例代码如下: ```cpp class Complex { public: Complex(double real = 0.0, double imag = 0.0) : m_real(real), m_imag(imag) {} // 成员函数重载加法运算符 Complex operator+(const Complex& other) const { return Complex(m_real + other.m_real, m_imag + other.m_imag); } // 声明友元函数 friend Complex operator+(const Complex& c1, const Complex& c2); private: double m_real; // 实部 double m_imag; // 虚部 }; ``` 这里我们为复数类定义了一个默认构造函数,以及一个成员函数重载加法运算符。 接下来,我们使用友元函数来实现复数的加法运算,示例代码如下: ```cpp // 友元函数重载加法运算符 Complex operator+(const Complex& c1, const Complex& c2) { return Complex(c1.m_real + c2.m_real, c1.m_imag + c2.m_imag); } ``` 在这个友元函数中,我们可以直接访问复数类的私有成员变量,从而实现复数的加法运算。 接下来,我们可以编写一个测试程序来验证我们的实现是否正确,示例代码如下: ```cpp #include <iostream> using namespace std; int main() { Complex c1(1.0, 2.0); Complex c2(3.0, 4.0); Complex c3 = c1 + c2; // 使用成员函数重载加法运算符 Complex c4 = operator+(c1, c2); // 使用友元函数重载加法运算符 cout << "c1 + c2 = " << c3.real() << " + " << c3.imag() << "i" << endl; cout << "c1 + c2 = " << c4.real() << " + " << c4.imag() << "i" << endl; return 0; } ``` 在这个测试程序中,我们别使用了成员函数友元函数重载加法运算符,并输出了计算结果。 这样,我们就完成了使用成员函数友元函数重载实现复数的加法运算的实验要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值