C++核心编程---友元

目录

友元

[友元的关键字 friend](#友元的关键字 friend)

友元的三种实现方式

[1. 全局函数做友元](#1. 全局函数做友元)

[2. 类做友元](#2. 类做友元)

[3. 成员函数做友元](#3. 成员函数做友元)


友元

生活中你的家有客厅(Public),有你的卧室(Private)

客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去

但是呢,你也可以允许你的好闺蜜好基友进去。

在程序中,有些私有属性 也想让一些特殊的类或者类外特殊的函数访问,需要友元。

友元的目的是让一个函数或者类访问另一个类中的私有成员

类的主要特点是封装性,即类的私有成员只能被它自己的成员函数访问,类外的函数无法访问类的私有成员。有时候,外部函数需要直接访问类的私有数据成员,以便提高效率,这时就可以把这个外部函数定义为该类的友元函数。这种在某个类定义中用friend声明一个外部函数(也许是其他类的成员函数)的方法,就好像宣布了一种"亲友"关系,这个外部虽然不是该类的成员函数,却可以访问该类的所有成员,无论是公有成员还是私有成员。

如果没有友元机制,则只能将类的所有成员都定义为公有的,任何函数都可以无约束地访问它,但是这样做就破坏了类的封装性。而友元机制可以在不破坏类的封装性的前提下,提高类成员访问的灵活性。

友元函数常常是一个类的一个成员函数,这样通过友元函数可以使一个类对象直接访问另一个类对象的私有成员。这种成员函数不仅可以访问自己所在本类对象中的私有成员,还可以访问friend声明所在类的对象中的私有与公有成员。

当友元函数是另一个类的成员函数时,还应该在另一个类中声明它的友元关系。声明语句的格式为:

friend<函数类型><类名>::<函数名>(<形参表>);

说明:

(1)友元函数虽然可以访问对象的私有成员,但它毕竟不是类的成员函数,因此,在类的外部定义友元函数时,不必像成员函数那样在函数名之前加上"类名::"。

(2)友元函数一般带有一个该类的入口参数。因为友元函数不是类的成员,所以它不能直接引用对象成员的名字,也不能通过this指针引用对象成员。它必须通过作为入口参数传递过来的对象名或对象指针来引用该对象的成员。

友元的关键字 friend

友元的三种实现方式

  1. 全局函数做友元

  2. 类做友元

  3. 成员函数做友元

1. 全局函数做友元

示例:

cpp 复制代码
#include<iostream>

#include<string>

using namespace std;

 

// 房屋的类

class building{

    // 设置 good 函数为友元 可以访问私有属性

    friend void good(building &Building);

public:

    building()

    {

        m_sittingroom = "客厅";

        m_bedroom = "卧室";

    }

    string m_sittingroom;

 

private:

    string m_bedroom;

};

 

// 全局函数

void good(building &Building)

{

    cout<<"全局函数访问:"<<Building.m_sittingroom<<endl;

    cout<<"全局函数访问:"<<Building.m_bedroom<<endl;

}

int main()

{

    building Building;

    good(Building);

    return 0;

}

运行结果:

2. 类做友元

示例:

cpp 复制代码
#include<iostream>

#include<string>

using namespace std;

 

class building;

 

class good_g{

public:

    good_g();

    void visit(); // 参观访问Building中的属性

private:

    building *Building;

};

 

 

// 房屋的类

class building{

    // 设置good_g为本类的友元

    friend class good_g;

 

public:

    building();

    string m_sittingroom;

 

private:

    string m_bedroom;

};

 

// 类外写成员函数

building::building()

{

    this->m_sittingroom = "客厅";

    this->m_bedroom = "卧室";

}

good_g::good_g()

{

    // 创建一个建筑物对象

    Building = new building; // 在堆区创建一个对象

}

void good_g::visit()

{

    cout<<"good_g类正在访问:"<<Building->m_sittingroom<<endl;
    
    cout<<"good_g类正在访问:"<<Building->m_bedroom<<endl;

}

void test01()

{

    good_g gg;

    gg.visit();

}

int main()

{

 

    test01();

    return 0;

}

运行结果:

3. 成员函数做友元

示例:

cpp 复制代码
#include<iostream>

#include<string>

using namespace std;



class building;



class good_g {

public:

    good_g();

    void visit(); // 参观访问Building中的属性

    void visit2(); // 访问不到building中的私有成员

private:

    building* Building;

};





// 房屋的类

class building {

    // good_g 类下的函数作为本类的友元,要加作用域才可以访问私有内容

    friend void good_g::visit();



public:

    building();



public:

    string m_sittingroom;



private:

    string m_bedroom;

};



// 类外写成员函数

building::building()

{

    this->m_sittingroom = "客厅";

    this->m_bedroom = "卧室";

}

good_g::good_g()

{

    // 创建一个建筑物对象

    Building = new building; // 在堆区创建一个对象

}

void good_g::visit()

{

    cout << "visit 正在访问:" << Building->m_sittingroom << endl;

    cout << "visit 正在访问:" << Building->m_bedroom << endl;

}

void good_g::visit2()

{

    cout << "visit2 正在访问:" << Building->m_sittingroom << endl;

    //cout<<"visit2 正在访问:"<<Building->m_bedroom<<endl;

    // visi2 访问不到buiding类中的私有成员,没有设置友元

}

void test01()

{

    good_g gg;

    gg.visit();

    gg.visit2();

}

int main()

{



    test01();

    return 0;

}

运行结果:

相关推荐
yaoxin5211236 分钟前
289. Java Stream API - 从字符串的字符创建 Stream
java·开发语言
清 澜11 分钟前
c++高频知识点总结 第 1 章:语言基础与预处理
c++·人工智能·面试
癫狂的兔子14 分钟前
【Python】【Flask】抽奖功能
开发语言·python·flask
你怎么知道我是队长15 分钟前
C语言---无名位域
c语言·开发语言
fqbqrr30 分钟前
2601C++,模块基础
c++
带土130 分钟前
6. C++智能指针(1)
开发语言·c++
海南java第二人38 分钟前
SpringBoot启动流程深度解析:从入口到容器就绪的完整机制
java·开发语言
星火开发设计42 分钟前
C++ queue 全面解析与实战指南
java·开发语言·数据结构·c++·学习·知识·队列
橘颂TA1 小时前
【剑斩OFFER】算法的暴力美学——力扣 394 题:字符串解码
数据结构·c++·结构与算法
DICOM医学影像1 小时前
2. go语言从零实现以太坊客户端-查询区块链账户余额
开发语言·golang·区块链·以太坊·web3.0·hardhat