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, 不過為了兼容性還是建議寫上。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM