成员函数做友元时,为什么成员函数需要在类外定义,以及类的定义顺序的注意事项

今天在老师讲友元的知识点时,我发现老师在使用成员函数做友元时,是在外定义成员函数,于是我当时就在想为什么不在类内部进行呢?于是我亲自去实操了一下(以下是完整代码的一部分):

class prson_A;//先声明prson_A,因为在prson_B中有使用到它

class prson_B{
    friend void prson_A::visit_name(prson &P);//友元函数的声明
private:
    string name;//私人属性
public:
    prson_B(string x="xxx"): name(x){;}//使用初始化列表实现name的初始化
};

class prson_A{
public:
    void visit_name(prson &P){//输出P的私人属性name的值
        cout<<P.name;
    }
};

此时我们去编译就会发现编译器报错:"invalid use of incomplete type 'class prson_A",而问题则出在了(简单说"就是定义顺序出了问题导致编译器处理了未知的对象"):

friend void prson_A::visit_name(prson_B &P);

此出报错的原因是:虽然一开始声明了"class prson_A;"但可能只是告诉编译器有这么一个类,但类内部的具体对象编译器也不知道,所以编译器在一开始运行到此处时,并不知道prson_A中存在visit_name这个函数,也就会报错'类的定义不完整'。

--------------------------------------------------------------------------

打个比方:就是老师在你报名时知道了你叫什么,但不知道你的具体个人信息,如你喜不喜欢吃苹果。

为了解决这个问题我将代码做了定义顺序的变换:

class prson_B;//-----------------注意此处应该声明的是prson_B了

class prson_A{
public:
    void visit_name(prson &P){//输出P的私人属性name的值
        cout<<P.name;
    }
};

class prson_B{
    friend void prson_A::visit_name(prson &P);//友元函数的声明
private:
    string name;//私人属性
public:
    prson_B(string x="xxx"): name(x){;}//使用初始化列表实现name的初始化
};

然而当我一旦编译后代码任然报错:"prson_B' has not been declared",而这一次报错的原因则是因为:(小编认为其原理也与之前差不多,也是对还未定义的东西进行编译

void visit_name(prson_B &P){

        cout<<P.name;

由于代码在执行到该处时,只知道存在一个名叫prson_B的类,但还不知道其内部有一个变量name,故而报错。

}

为此我们要想解决这个问题,我们就需要在完全定义好prson_A,prson_B后,然后在定义prson_B的visit_name函数,所以老师们才会使用外部定义函数的方法来规避这些问题:(以下是完整代码)

#include<iostream>

#include<string>

using namespace std;

class prson_B;//提前声明prson_B这个类

class prson_A{

public:

    void visit_name(prson_B &P);//仅声明函数,不对还未定义的部分进行编译

};

class prson_B{

    friend void prson_A::visit_name(prson_B &P);//

private:

    string name;

public:

    prson_B(string x="xxx"): name(x){;}

};

void prson_A::visit_name(prson_B &P){

    cout<<"报告老师我喜欢吃"<<P.name;

}

int main(){

    prson_B P("苹果");

    prson_A P2;

    P2.visit_name(P);

    system("pause");//暂停执行,以便显示

    return 0;

}       

 --------------------------------------------------------------------------------------------------------------------------------

以上是仅仅是个人见解!!!,如果有什么不对的地方,还请大家指正。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值