0
点赞
收藏
分享

微信扫一扫

C++友元知识点详解

蓝哆啦呀 2022-04-06 阅读 88
c++

1.何为友元?

类可以允许其他类或者函数访问它的非公有成员,方式是令其他类或者函数成为它的友元(需要用到friend关键字)。

2.友元分类

3.非成员函数作为友元函数

示例代码结构如下:

// Student.hpp

#ifndef STUDENT_HPP
#define STUDENT_HPP

class Student {
public:

    friend void ModifyAge( Student &stu, int value );
    Student():age(18){}
    ~Student(){}
    int GetAge(){
        return age;
    }
private:
    void SetAge( int tmp ){
        age = tmp;
    }
    int age;   
};
void ModifyAge( Student &stu, int value );
#endif /* STUDENT_HPP */

// Student.cpp

#include "Student.hpp"

void ModifyAge( Student &stu, int value ){
    stu.SetAge(value);
}
// main.cpp


#include <iostream>
#include "Student.hpp"

using namespace std;


int main( void ){
    Student a;
    cout << a.GetAge() << endl;
    ModifyAge( a, 25 );
    cout << a.GetAge() << endl;
    return 0;
}

友元声明只能出现在类定义的内部,但是在类内出现的具体位置没有限制。

并且友元不是类的成员,不受它所在区域,访问控制级别的约束(不受public,private的约束)。

如果我们没有在类的外部对ModifyAge函数进行声明,main.cpp的内容如下所示:

// main.cpp

#include <iostream>
//#include "Student.hpp"	Student.hpp替换为下面的内容


class Student {
public:

    friend void ModifyAge( Student &stu, int value );
    Student():age(18){}
    ~Student(){}
    int GetAge(){
        return age;
    }
private:
    void SetAge( int tmp ){
        age = tmp;
    }
    int age;   
};


using namespace std;

int main( void ){
    Student a;
    cout << a.GetAge() << endl;
    ModifyAge( a, 25 );			// 这里在编译时会报错,在当前文件中,找不到ModifyAge函数的声明
    cout << a.GetAge() << endl;
    return 0;
}

4.类是友元

示例代码结构如下:

 

// Student.hpp


#ifndef STUDENT_HPP
#define STUDENT_HPP


class Student {
public:
    friend class Teacher;
    Student():age(18){}
    ~Student(){}
    int GetAge(){
        return age;
    }
private:
    void SetAge( int tmp ){
        age = tmp;
    }
    int age;   
};
#endif /* STUDENT_HPP */
// Teacher.hpp



#ifndef TEACHER_HPP
#define TEACHER_HPP

#include "Student.hpp"

class Teacher {
public:
    Teacher() = default;
    virtual ~Teacher();
    void SetStudentAge( Student &stu, int value );
private:

};

#endif /* TEACHER_HPP */
// Teacher.cpp


#include "Teacher.hpp"


Teacher::~Teacher() {
}


void Teacher::SetStudentAge( Student &stu, int value ){
    stu.SetAge(value);
}
// main.cpp


#include <iostream>
#include "Student.hpp"
#include "Teacher.hpp"

using namespace std;

int main( void ){
    Student a;
    cout << a.GetAge() << endl;
    
    Teacher t1;
    t1.SetStudentAge(a,30);
    cout << a.GetAge() << endl;
        
    return 0;
}

5.类的成员函数是友元

示例代码结构如下:

 

// Student.hpp

#ifndef STUDENT_HPP
#define STUDENT_HPP

// 这里包含Teacher1的头文件,是因为友元声明中用到了Teacher1::
#include "Teacher1.hpp"

class Student {
public:
    friend void Teacher1::SetStuAge( Student &stu, int value );
    Student():age(18){}
    ~Student(){}
    int GetAge(){
        return age;
    }
private:
    void SetAge( int tmp ){
        age = tmp;
    }
    int age;   
};
#endif /* STUDENT_HPP */

// Teacher1.hpp

#ifndef TEACHER1_HPP
#define TEACHER1_HPP

// 注意:这里没有包含Student的头文件
class Student;  // 这里用的是不完全类型

class Teacher1 {
public:
    Teacher1();
    void SetStuAge( Student &stu, int value );
    virtual ~Teacher1();
private:

};

#endif /* TEACHER1_HPP */
// Teacher1.cpp


#include "Teacher1.hpp"
#include "Student.hpp"    // 这里包含了Student头文件
Teacher1::Teacher1() {
}


Teacher1::~Teacher1() {
}


void Teacher1::SetStuAge( Student &stu, int value ){
    stu.SetAge(value);
}
// main.cpp

#include <iostream>
#include "Student.hpp"
#include "Teacher1.hpp"

using namespace std;

int main( void ){
    Student a;
    cout << a.GetAge() << endl;

    Teacher1 t2;
    t2.SetStuAge(a,35);
    cout << a.GetAge() << endl;
    
    return 0;
}

到这里三种友元类型的示例都展示完成了。

最不好理解的就是成员函数作为友元的情况,需要组织好类的结果,不然编译时,很容易报错。

下面对第三种情况做一个总结。

类B有一个成员函数B::func(),是类A的友元,那么三者需要按照下面的顺序进行组织:

  • 首先定义类B,声明func函数,但是不能定义它。同时需要在定义类B之前,声明类A(不完整声明)。
  • 定义类A,包括对B::func函数的友元声明(#include "B.hpp")。
  • 最后定义B::func,此时它才可以使用类A的私有成员。
举报

相关推荐

[C++]友元

C++友元

C++ 友元

C++友元函数和友元类

c++ 友元函数

0 条评论