【C++ OOP 03 友元】各种友元例子以及如何类外写成员函数
【友元】
在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术
友元的目的就是让一个函数或者类 访问另一个类中私有成员
友元的关键字为 friend
友元的三种实现
- 全局函数做友元
- 类做友元
- 成员函数做友元
全局函数友元
新建一个Building类,里面有客厅(public)和卧室(private)两个属性
class Building {
//行为
public:
//构造函数
Building() {
m_SittingRoom = "客厅";
m_BadRoom = "卧室";
}
//属性
public:
string m_SittingRoom;
private:
string m_BadRoom;
};
int main() {
system("pause");
return 0;
}
在main外部(全局)创建一个函数goodGay,分别访问两个属性。
使用test01函数测试,当然私有属性要访问时会报错
class Building {
//行为
public:
//
Building() {
m_SittingRoom = "客厅";
m_BadRoom = "卧室";
}
//属性
public:
string m_SittingRoom;
private:
string m_BadRoom;
};
void goodGay(Building *building) {
cout << "好基友正在访问: " << building->m_SittingRoom << endl;
//cout << "好基友正在访问: " << building->m_BedRoom << endl;
}
void test01() {
Building building;
goodGay(&building);
}
int main() {
test01();
system("pause");
return 0;
}
这时,需要将void goodGay(Building *building)添加到Building类的开头,并以关键字‘friend’修饰
#include<iostream>
using namespace std;
#include<string>
class Building {
//声明友元
friend void goodGay(Building* building);
//行为
public:
//
Building() {
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
//属性
public:
string m_SittingRoom;
private:
string m_BedRoom;
};
void goodGay(Building *building) {
cout << "好基友正在访问: " << building->m_SittingRoom << endl;
cout << "好基友正在访问: " << building->m_BedRoom << endl;
}
void test01() {
Building building;
goodGay(&building);
}
int main() {
test01();
system("pause");
return 0;
}
由此,友元全局函数goodGay便可以访问Building类中的私有属性
类友元
例子的框架与之前类似
只是这次我们需要创建一个GoodGay类去访问
补充知识点:类外写成员函数
例如,现在有一个Building类
class Building
{
public:
Building();
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom;//卧室
};
int main(){
system("pause");
return 0;
}
该类中的构造函数(也是成员函数之一)只是声明还没有实现,我们可以在类外对其进行实现
class Building
{
public:
Building();
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom;//卧室
};
//类外实现成员函数
//"xxx :: xx函数",xxx表示声明了函数的作用域
Building::Building()
{
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
int main(){
system("pause");
return 0;
}
例子
根据上面的方法,我们在GoodGay类和Building类外面分别实现其构造函数
#include<iostream>
using namespace std;
#include<string>
class Building;
class goodGay
{
public:
goodGay();
void visit();
private:
Building *building;
};
class Building
{
//告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容
friend class goodGay;
public:
Building();
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom;//卧室
};
//类外实现构造函数Building()
//作用域在Building类下
Building::Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
//类外实现goodGay构造函数
//作用域在goodGay类下
goodGay::goodGay()
{
//在堆区创建建筑物对象
//goodGay类中的Building *building指向该对象
building = new Building;
}
//类外实现goodGay的成员函数
//作用域在goodGay类下
void goodGay::visit()
{
cout << "好基友正在访问" << building->m_SittingRoom << endl;
cout << "好基友正在访问" << building->m_BedRoom << endl;
}
void test01()
{
goodGay gg;
gg.visit();
}
int main(){
test01();
system("pause");
return 0;
}
GoodGay类能访问Building类的私有属性的关键也是使用友元
即在Building类开头用‘friend’修饰
class Building
{
//告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容
friend class goodGay;
public:
...
成员函数友元
例子
#include<iostream>
using namespace std;
#include<string>
class Building;
class goodGay
{
public:
goodGay();
void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容
void visit2();
private:
Building *building;
};
class Building
{
//告诉编译器 goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容
friend void goodGay::visit();
public:
Building();
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom;//卧室
};
//类外实现构造函数Building()
//作用域在Building类下
Building::Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
//类外实现构造函数goodGay()
//作用域在goodGay类下
goodGay::goodGay()
{
building = new Building;
}
//类外实现成员函数visit()
//作用域在goodGay类下
void goodGay::visit()
{
cout << "好基友正在访问" << building->m_SittingRoom << endl;
cout << "好基友正在访问" << building->m_BedRoom << endl;
}
//类外实现成员函数visit2()
//作用域在goodGay类下
void goodGay::visit2()
{
cout << "好基友正在访问" << building->m_SittingRoom << endl;
//cout << "好基友正在访问" << building->m_BedRoom << endl;
}
void test01()
{
goodGay gg;
gg.visit();
}
int main(){
test01();
system("pause");
return 0;
}
技巧
如果之后要用到某个类,但是该类的细节还没有写,可以先写个占位的代码
class Building;
class goodGay{
public:
goodGay();
void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容
void visit2();
private:
//用到了但还没写
Building *building;
};
...
//之后再定义
class Building{
}
【C++ OOP 03 友元】各种友元例子以及如何类外写成员函数的更多相关文章
- c++友元函数、友元类、友成员函数
友元函数:不是类成员函数,是一个类外的函数,但是可以访问类所有成员. class Point{ public: friend void fun(Point t);//友元函数 private: int ...
- C++ 友元(friend关键字)、类中的重载、操作符重载(operator关键字)
C++ 中友元的用法: 1.在类中使用friend关键字声明 2.类的友元可以是其它类或者具体函数 3.友元不是类的一部分 4.友元不受类中访问级别的限制 5.友元可以直接访问具体类中的所有成员. 友 ...
- 友元(友元函数、友元类和友元成员函数) C++
有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的.例如被重载的操作符,如输入或输出操作符,经常需要访问类的私有数据成员. 友元(frend)机制允许一个类将 ...
- C++友元(友元函数、友元类和友元成员函数)
友元(友元函数.友元类和友元成员函数) C++ 有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的.例如被重载的操作符,如输入或输出操作符,经常需要访问类的私 ...
- C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...
- C++ 友元 (全局函数做友元) (类做友元) (成员函数做友元)
1 //友元 全局函数做友元 2 /* 3 #include <iostream> 4 #include <string> 5 using namespace std; 6 7 ...
- C++基础-4-封装(构造函数与析构函数,深拷贝与浅拷贝,静态成员,this,友元,const修饰成员函数)
4. 封装 4.1.1 封装的意义 1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 con ...
- 读书笔记 effective c++ Item 23 宁可使用非成员非友元函数函数也不使用成员函数
1. 非成员非友元好还是成员函数好? 想象一个表示web浏览器的类.这样一个类提供了清除下载缓存,清除URL访问历史,从系统中移除所有cookies等接口: class WebBrowser { pu ...
- C++运算符重载三种形式(成员函数,友元函数,普通函数)详解
首先,介绍三种重载方式: //作为成员函数重载(常见) class Person{ Private: string name; int age; public: Person(const char* ...
- 重载运算符:类成员函数or友元函数
类成员函数: bool operator ==(const point &a)const { return x==a.x; } 友元函数: friend bool operator ==(co ...
随机推荐
- vue中keep-alive详细讲解
场景 今天产品跑过来跟我说, 当我在A页面修改数据后,去B页面. 然后返回A页面.希望A页面保留我修改后的数据. 而不是数据又恢复最初的样子了.我心里想,尼玛,又要加班了? 看下面小粒子 数据被被重置 ...
- 小程序跳转到h5页面无法获取参数
在小程序中,遇见这样一个需求: 小程序(携带token)跳转到H5页面: 在H5端取token;将token作为参数: 然后返回来的信息, 这里遇见一个问题,在created中无法获取地址栏的参数: ...
- 临上线项目使用ILRuntime热更
前言 我们有一个用Unity引擎开发了二十个月的mmo arpg手游项目,在安卓已经测试三轮了,出于IOS的热的考虑且结合我们的情况:全部代码都是纯C#开发非Lua,所以计划使用ILRuntime热更 ...
- 获取Visual Studio所用MSVC编译器版本:_MSC_VER数值
本文介绍查看Visual Studio软件_MSC_VER值的方法. _MSC_VER是微软公司推出的C/C++编译器--MSVC编译器的一个内置宏,其值表示当前Visual Studio软件 ...
- ElasticSearch实战指南必知必会:安装分词器、高级查询、打分机制
ElasticSearch实战指南必知必会:安装中文分词器.ES-Python使用.高级查询实现位置坐标搜索以及打分机制 1.ElasticSearch之-安装中文分词器 elasticsearch ...
- C/C++ 文件与指针操作笔记
创建临时文件 #include <stdio.h> int main(int argc, char *argv[]) { FILE *temp; char c; if ((temp = t ...
- 使用Nuget快速集成.Net三维控件
据老一辈的程序员说开发三维程序门槛很高,需要学若干年才能入门,自从遇上AnyCAD三维控件后,开发三维应用变的简单了.当结合nuget后,一切更简单了. 1 准备工作 安装VS201x以后,就可以开始 ...
- 实战视频所需要的IDE和工具软件的下载链接
以下是视频实战所需要的IDE和工具软件的下载链接: Visual Studio Code(适用于Windows.Mac和Linux):https://code.visualstudio.com/dow ...
- ZR 七连 Day 1 游记
ZR 七连 Day 1 游记 游记篇 赛前搞笑事件 今天是第一场正睿,还是要 好好对待 的 $ 17:59:58 $ 还在吃饭 $ 17:59:59 $ 做出重要决定,先打着比赛,有空就吃一口包子 $ ...
- 19.2 显式加载/隐式加载--《Windows核心编程》
部分笔记来自于:https://blog.csdn.net/blade1080/article/details/81364161 注:关于DLL存放位置,一般是放到可执行文件的目录下. 下面时加载程序 ...