c++友元函数和友元类详解

/* c++友元函数和友元类详解 */
/* 只有本类中的函数可以访问本类的 private 成员,借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数(普通函数?)访问当前类的 private 成员*/
/* 友元函数可以访问当前类中的所有成员,包括 public、protected、private 属性的 */
/* 在类外定义,在类中声明,不属于当前类的函数,前面加上friend关键字构成友元函数,友元函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数 */

/*1、将非成员函数声明为友元函数 */
#include <iostream>
using namespace std;
namespace LL
{
    class Student
    {
    public:
        Student(char *name, int age, float score);

    public:
        friend void show(Student *pstu); //将show()声明为友元函数
    private:
        char *m_name;
        int m_age;
        float m_score;
    };
    Student::Student(char *name, int age, float score) : m_name(name), m_age(age), m_score(score) {}
    //非成员函数
    //友元函数不同于类的成员函数,在友元函数中不能直接访问类的成员,必须要借助对象
    void show(Student *pstu)
    {
        cout << pstu->m_name << "的年龄是 " << pstu->m_age << ",成绩是 " << pstu->m_score << endl;
    }
}
int main0()
{
    LL::Student stu("小明", 15, 90.6);
    LL::show(&stu); //调用友元函数
    LL::Student *pstu = new LL::Student("李磊", 16, 80.5);
    LL::show(pstu); //调用友元函数
    return 0;
}

/* 2、将其他类的成员函数声明为友元函数 */
/* 一个函数可以被多个类声明为友元函数,这样就可以访问多个类中的 private 成员 */
namespace LL1
{

    class Address; //提前声明address类,不能生成对象
    //声明Student类
    class Student
    {
    public:
        Student(char *name, int age, float score);

    public:
        void show(Address *addr); //用该类的名字去定义指向该类型对象的指针变量,还没有具体对象

    private:
        char *m_name;
        int m_age;
        float m_score;
    };
    //声明Address类
    class Address
    {
    private:
        char *m_province; //省份
        char *m_city;     //城市
        char *m_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) : m_name(name), m_age(age), m_score(score) {}
    void Student::show(Address *addr)
    {
        cout << m_name << "的年龄是 " << m_age << ",成绩是 " << m_score << endl;
        cout << "家庭住址:" << addr->m_province << "省" << addr->m_city << "市" << addr->m_district << "区" << endl;
    }
    //实现Address类
    Address::Address(char *province, char *city, char *district)
    {
        m_province = province;
        m_city = city;
        m_district = district;
    }
}
int main1()
{
    LL1::Student stu("小明", 16, 95.5f);
    LL1::Address addr("陕西", "西安", "雁塔");
    stu.show(&addr);

    LL1::Student *pstu = new LL1::Student("李磊", 16, 80.5);
    LL1::Address *paddr = new LL1::Address("河北", "衡水", "桃城");
    pstu->show(paddr);
    return 0;
}

/* 3、友元类 */
/* 友元类中的所有成员函数都是另外一个类的友元函数 */
/* 友元的关系是单向的而不是双向的。如果声明了类 B 是类 A 的友元类,不等于类 A 是类 B 的友元类 */
/* 友元的关系不能传递。如果类 B 是类 A 的友元类,类 C 是类 B 的友元类,不等于类 C 是类 A 的友元类。 */
class Address; //提前声明Address类
//声明Student类
class Student
{
public:
    Student(char *name, int age, float score);

public:
    void show(Address *addr);

private:
    char *m_name;
    int m_age;
    float m_score;
};
//声明Address类
class Address
{
public:
    Address(char *province, char *city, char *district);

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

private:
    char *m_province; //省份
    char *m_city;     //城市
    char *m_district; //区(市区)
};
//实现Student类
Student::Student(char *name, int age, float score) : m_name(name), m_age(age), m_score(score) {}
void Student::show(Address *addr)
{
    cout << m_name << "的年龄是 " << m_age << ",成绩是 " << m_score << endl;
    cout << "家庭住址:" << addr->m_province << "省" << addr->m_city << "市" << addr->m_district << "区" << endl;
}
//实现Address类
Address::Address(char *province, char *city, char *district)
{
    m_province = province;
    m_city = city;
    m_district = district;
}
int main()
{
    Student stu("小明", 16, 95.5f);
    Address addr("陕西", "西安", "雁塔");
    stu.show(&addr);

    Student *pstu = new Student("李磊", 16, 80.5);
    Address *paddr = new Address("河北", "衡水", "桃城");
    pstu->show(paddr);
    return 0;
}
上一篇:Reversing Linked List


下一篇:Redis实现微博后台业务逻辑系列(三)