前言
本文主要讲解C++语言中友元函数做类成员时需要注意的事项,并且将分别以分文件和不分文件两种形式来讲解编写友元函数做类成员时的具体要求.
作者本人接触C++的时间不长,第一次遇到类成员函数做友元的问题时,也是四处碰壁,琢磨了一天,整理出了这篇文章,也希望这篇文章能够帮助到C++小白加深对类成员函数做友元的理解与应用,同时,时间仓促写出本文,诸多不足,敬请指正
一、友元是什么?
在C++中,友元(Friend)是一种特殊的机制,它允许某个函数或类访问另一个类的私有(private)或保护(protected)成员,即使这些成员原本不允许外部访问。
二、友元的使用方法
1.非成员函数做友元
2.成员函数做友元
3.类成员函数做友元
本文主要讲解第3种使用方法----类成员函数做友元
三、
1.题目引入
实现一个C++程序,其中Goodgay类的成员函数可以访问Building类的私有成员。要求使用前向声明解决类依赖问题,并通过友元函数授予访问权限,同时正确管理动态内存。
2.基本思路
我们需要定义Goodgay类与Building类,Building类中存在私有成员变量m_bedroom,在Goodgay类中需要定义一个visitBuilding函数作为Building类的友元去访问Building类中的私有成员.
3.代码实现
(1).不分文件编写
因为是Building将Goodgay的成员函数当作友元,所以要先定义Goodgay类,才能在定义Building类时将Goodgay的成员函数当作友元
在前向声明Building后,再定义Goodgay类.
告诉编译器有Building类,类中有哪些函数,哪些成员变量,编译器并不知道,编译器只知道,是的,有这么个类。
//1.一定要写Building类前向声明,告诉编译器有Building这个类
//以便于Goodgay类中可以使用Building类对象作为成员
class Building;
//Goodgay类定义
class Goodgay {
public:
string m_name;
Building* building;
Goodgay();
~Goodgay();
void visitBuilding();//访问Building私有成员的函数
//2.一定要先声明visitBuilding函数,等定义Builing类之后再去定义getBuilding函数
//因为此时编译器并不知道Building类中有什么成员,也无法访问Building类成员
};
定义Building类
//Building类定义
class Building {
friend void Goodgay::visitBuilding(); //3.声明友元函数
private:
string m_bedroom;
public:
string m_livingroom;
Building(string bedroom, string livingroom) :m_bedroom(bedroom), m_livingroom(livingroom) {}
};
类函数实现:类内函数的类外实现,可以有效降低类之间的编译耦合
Goodgay::Goodgay() //构造函数分配内存
{
building = new Building("卧室", "客厅");
}
Goodgay::~Goodgay() //析构函数释放内存
{
if (building == NULL)
return;
delete building;
building = NULL;
}
void Goodgay::visitBuilding()
{
cout <<"Goodgay正在访问"<< building->m_bedroom << endl;//访问私有成员
cout << "Goodgay正在访问"<<building->m_livingroom << endl;//访问公有成员
}
主函数:实例化Goodgay对象,并调用visitBuilding函数
int main()
{
Goodgay G;
G.visitBuilding();
system("pause");
return 0;
}
运行结果
(2).分文件编写
----具体逻辑和不分文件编写差不多,但是需要注意头文件
代码结构
Building.h:需要包含Goodgay.h头文件,因为Building的定义中包含了Goodgay类中的成员函数visitBuilding,不加Goodgay.h头文件编译器无法识别visitBuilding函数
#pragma once
#include<iostream>
#include<string>
#include"Goodgay.h" //引入Goodgay头文件,告诉编译器Goodgay类中包含visitBuilding函数
class Building {
friend void Goodgay::visitBuilding();
private:
std::string m_bedroom;
public:
std::string m_livingroom;
Building(std::string bedroom, std::string livingroom);
};
Building.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"Building.h"
Building::Building(std::string bedroom, std::string livingroom) :m_bedroom(bedroom), m_livingroom(livingroom) {}
Goodgay.h:包含类Building前向文件即可,告诉编译器有Building类
#pragma once
#include<iostream>
#include<string>
class Building;
class Goodgay {
public:
std::string m_name;
int m_age;
Building * building;
Goodgay(std::string name, int age);
~Goodgay();
void visitBuilding(); //访问Building类成员
};
Goodgay.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"Goodgay.h"
#include"Building.h"
Goodgay::Goodgay(std::string name, int age) :m_name(name)
{
building = new Building("卧室", "客厅");
}
Goodgay::~Goodgay()
{
if (building == NULL)
return;
delete building;
building = NULL;
}
void Goodgay::visitBuilding()
{
std::cout << "building的卧室为" << building->m_bedroom << std::endl;
std::cout << "building的客厅为" << building->m_livingroom << std::endl;
}
main.cpp:主函数包含Building.h和Goodgay.h,实例化Goodgay对象,调用visitBuilding函数访问Building私有成员
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include"Building.h"
#include"Goodgay.h"
int main()
{
Goodgay G("杜维", 18);
G.visitBuilding();
system("pause");
return 0;
}
运行结果
四、总结
以上就是本文的所有内容,友元的主要目的是提供更灵活的访问控制,以便在某些情况下,外部函数或类能够直接操作类的内部数据,当我们需要使用到友元时,我们只需要在类中提前声明就可以,声明时通常是,在前面加关键字friend,但是需要注意的是,要谨慎使用友元,避免破坏封装性.