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

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

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;

}       

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

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

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-05 16:40:01       91 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-05 16:40:01       97 阅读
  3. 在Django里面运行非项目文件

    2023-12-05 16:40:01       78 阅读
  4. Python语言-面向对象

    2023-12-05 16:40:01       88 阅读

热门阅读

  1. Flyway——Oracle创建前缀索引

    2023-12-05 16:40:01       62 阅读
  2. oracle 19c rac 安装手册

    2023-12-05 16:40:01       45 阅读
  3. mysql学习记录

    2023-12-05 16:40:01       42 阅读
  4. Oracle之ORA-29275: 部分多字节字符

    2023-12-05 16:40:01       62 阅读
  5. Redis下载安装教程(详细步骤)

    2023-12-05 16:40:01       64 阅读
  6. Python实现pdf文件转word文件

    2023-12-05 16:40:01       56 阅读
  7. MySQL数据库命令详解(二)

    2023-12-05 16:40:01       58 阅读
  8. 国防科技大博士招生入学考试【50+论文主观题】

    2023-12-05 16:40:01       36 阅读
  9. 我的创作纪念日

    2023-12-05 16:40:01       51 阅读