zoukankan      html  css  js  c++  java
  • C++中的友元函数和友元类

    C++中的友元函数主要应用于以下场景:

    友元函数

    第一种场景

    代码中有一个全局函数,该函数想要去访问某个类的成员变量(该类的成员变量是private的,且该类并未提供任何获取获取私有成员变量的public方法),这时候可以在这个类中把该全局函数声明为友元函数,这样这个全局函数就具备了能够获取那个类的私有成员变量的资格。

    例:通过友元函数获取Person类的各项字段信息:

    main.cpp

    #include <iostream>
    #include "Person.h"
    
    void showPersonInfo(Person *person)
    {
        std::cout << person->m_name << ", age is: " << person->m_age << ", sex is: " << person->m_sex << std::endl;
    }
    int main()
    {
        Person *person = new Person("xp.chen", 20, 1);
        showPersonInfo(person);
        delete person;
    
        getchar();
        return 0;
    }

    person.h

    #pragma once
    class Person
    {
    private:
        char *m_name;
        int m_age;
        int m_sex;
    public:
        Person(char *name, int age, int sex);
        ~Person();
    public:
        friend void showPersonInfo(Person *person); // 将showPersonInfo()函数声明为友元函数
    };

    person.cpp

    #include "Person.h"
    
    Person::Person(char *name, int age, int sex)
    :m_name(name)
    , m_age(age)
    , m_sex(sex)
    {
    }
    
    Person::~Person()
    {
    }

    运行结果:

    xp.chen, age is: 20, sex is: 1

    第二种场景

    在某个类(假设为A类)有一个成员函数,该成员函数想去访问另一个类(假设为B类)中的私有成员变量。这时候则可以在第二个类(B类)中,声明第一个类(A类)的那个成员函数为友元函数,这样第一个类(A类)就可以访问第二个类(B类)的私有成员变量了。

    例:打印Person类的详细信息(包含姓名,年龄,性别,省份,城市,街道)

    Person.h

    #pragma once
    
    class Address;
    class Person
    {
    private:
        char *m_name;
        int m_age;
        int m_sex;
    public:
        Person(char *name, int age, int sex);
        ~Person();
    public:
        void showDetailInfo(Address *addr); // 用于打印包含姓名,年龄,性别,省份,城市,街道的详细信息
    };

    Address.h

    #pragma once
    #include "Person.h"
    
    class Address
    {
    private:
        char *m_province;
        char *m_city;
        char *m_district;
    
    public:
        Address(char *province, char *city, char *district);
        ~Address();
    public:
        friend void Person::showDetailInfo(Address *addr);
    };

    Address.cpp

    #include "Address.h"
    
    Address::Address(char *province, char *city, char *district)
    :m_province(province)
    , m_city(city)
    , m_district(district)
    {
    }
    
    Address::~Address()
    {
    }

    Person.cpp

    #include <iostream>
    #include "Address.h"
    
    Person::Person(char *name, int age, int sex)
    :m_name(name)
    , m_age(age)
    , m_sex(sex)
    {
    }
    
    void Person::showDetailInfo(Address *addr)
    {
        std::cout << "Name: " << m_name << ", Age: " << m_age << ", Sex: " << m_sex << ", Province: " << addr->m_province << ", City: " << addr->m_city << ", District: " << addr->m_district << std::endl;
    }
    
    Person::~Person()
    {
    }

    main.cpp

    #include <iostream>
    #include <stdlib.h>
    #include "Address.h"
    
    int main()
    {
        Person *person = new Person("xp.chen", 20, 1);
        Address *address = new Address("JS", "KS", "ZhengRoad");
        person->showDetailInfo(address);
    
        delete person, address;
        system("pause");
        return 0;
    }

    运行结果:

    Name: xp.chen, Age: 20, Sex: 1, Province: JS, City: KS, District: ZhengRoad

    友元类

    友元类则更简单,可以将一个类(类A)声明成另一个类(类B)的友元类,那么类A就拥有了能够访问类B所有成员的资格,包括private, protected, public的。

    例:将上述例子中的Address.h修改成:

    #pragma once
    #include "Person.h"
    
    class Address
    {
    private:
        char *m_province;
        char *m_city;
        char *m_district;
    
    public:
        Address(char *province, char *city, char *district);
        ~Address();
    public:
        friend class Person;
    };

    声明类Person是类Address的友元类,再次运行程序:

    Name: xp.chen, Age: 20, Sex: 1, Province: JS, City: KS, District: ZhengRoad

    需要注意的是:

    • 友元的关系是单向的而不是双向的。如果声明了类 B 是类 A 的友元类,不等于类 A 是类 B 的友元类,类 A 中的成员函数不能访问类 B 中的 private 成员。
    • 友元的关系不能传递。如果类 B 是类 A 的友元类,类 C 是类 B 的友元类,不等于类 C 是类 A 的友元类。

    另外,有的编译器也可以不写class关键字,也就是说可以写成:friend Person, 不过为了兼容性还是建议写上。

  • 相关阅读:
    如何修改 WordPress 的默认 Gravatar 头像
    解决wordpress部分博客文章页面无法显示的问题
    git删除本地所有的更改
    C++ char数组和string类简单使用总结
    c++ 中关于int,unsigned int , short的关系与应用
    CentOS下,mysql服务启动失败
    通过日志动态查看正在执行的mysql语句
    mysql 处理数据库中的重复行
    Linux cp复制
    在myeclipse中使用查找功能
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/9558498.html
Copyright © 2011-2022 走看看