C++的知识分享程序员IT@程序员猿媛

7. C++友元函数和友元类

2019-04-03  本文已影响6人  飞扬code

7.1 友元函数

C++只有本类中的函数可以访问本类的 private 成员。

但一种情况例外,那就是友元(friend)。友元可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。

在当前类以外定义的,不属于当前类的函数也可以在当前类中声明,但要在前面加 friend 关键字,这样的函数就是友元函数。

注意:友元函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数。

友元函数可以访问当前类中的所有成员(包括 public、protected、private修饰的成员)。

1、将非成员函数声明为友元函数。

#include <iostream>
using namespace std;

class Student{
public:
    Student(char *name, int age, float score);
public:
    friend void show(Student *pstu); //将show()声明为友元函数
private:
    char *name;
    int age;
    float score;
};
Student::Student(char *name, int age, float score): name(name), age(age), score(score){ }

//非成员函数
void show(Student *ps){
    cout<<ps->name<<"的年龄是 "<<ps->age<<",成绩是 "<<ps->score<<endl;
}

int main(){
    Student stu("豆豆", 18, 80.0);
    show(&stu); //调用友元函数
    Student *ps = new Student("呵呵", 17, 90.0);
    show(ps); //调用友元函数
    return 0;
}
image.png

注意:在友元函数中不能直接访问类的成员,必须要借助对象。

类的成员函数可以通过this指针完成属性的调用,但是友元函数无法使用this,所以在该函数内部需要为其传递一个对象的参数,用来调用属性,形参可以直接传递对象,也可以传递对象指针或对象引用。


7.2 将其他类的成员函数声明为友元函数

友元函数不仅可以是全局函数(非成员函数),还可以是另外一个类的成员函数。

#include <iostream>
using namespace std;

class Address; //提前声明Address类
//声明Student类
class Student{
public:
    Student(char *name, int age, float score);
public:
    void show(Address *addr);
private:
    char *name;
    int age;
    float score;
};

//声明Address类
class Address{
private:
    char *province; //省份
    char *city; //城市
    char *district; //区(市区)
public:
    Address(char *province, char *city, char *district);
    //将Student类中的成员函数show()声明为友元函数
    friend void Student::show(Address *addr);
};

//实现Student类
Student::Student(char *name, int age, float score): name(name), age(age), score(score){ }

void Student::show(Address *addr){
    cout<<name<<"的年龄是 "<<age<<",成绩是 "<<score<<endl;
    cout<<"家庭住址:"<<addr->province<<"省"<<addr->city<<"市"<<addr->district<<"区"<<endl;
}

//实现Address类
Address::Address(char *province, char *city, char *district){
    this->province = province;
    this->city = city;
    this->district = district;
}

int main(){
    Student stu("豆豆", 18, 80.0);
    Address addr("辽宁", "沈阳", "浑南");
    stu.show(&addr);
    Student *ps = new Student("呵呵", 17, 90.0);
    Address *paddr = new Address("辽宁", "大连", "甘井子");
    ps->show(paddr);
    return 0;
}
image.png

注意:一个函数可以被多个类声明为友元函数,这样就可以访问多个类中的 private 成员。


7.3 友元类

我们呢还可以将整个类声明为另一个类的友元类,这样友元类中的所有成员函数都是另外一个类的友元函数。

例如将类 B 声明为类 A 的友元类,那么类 B 中的所有成员函数都是类 A 的友元函数,可以访问类 A 的所有成员,包括 public、protected、private 属性的。

将Student类声明为Address类的友元类,在Address类中

public:
    //将Student类声明为Address类的友元类
    friend class Student;

注意:
1、友元的关系是单向的。
类 B 是类 A 的友元类,不等于类 A 是类 B 的友元类。
2、友元的关系不能传递。类 A 是类 B 的友元类,类 B 是类 C 的友元类,但类 A不是类 C 的友元类(朋友的朋友不一定也是朋友)。
3、为了数据的安全性,一般我们只声明友元函数,友元类极少使用。

上一篇 下一篇

猜你喜欢

热点阅读