在C++中我们可以將函数定义成类的友元函数,这样在函数中就可以访问类的私有成员。与函数相同,类也可以作为另一个类的友元类,在友元类中可以访问另外一个类的所有成员。

声明友元类的方法很简单,只需在类中写下如下语句:

friend class 类名;

接下来我们看一个案例,假如我们需要设计一个模拟电视机和遥控器的程序,代码如下。


#include <iostream>
using namespace std; class TV
{
private:
enum{on,off};
enum{minvol,maxvol=100};
enum{minchn,maxchn=40};
bool on_off;
int volume;
int channel;
public:
TV():on_off(off),volume(20),channel(3){};
//打印属性
void print_tv_info()
{
cout<<"on_off:"<<on_off<<endl;
cout<<"volume:"<<volume<<endl;
cout<<"channel:"<<channel<<endl;
}
//此处將TVController类声明为TV类的友元类
friend class TVController;
}; class TVController
{
public:
void set_status(TV& t){t.on_off = (t.on_off == t.on ? t.off : t.on);}
bool volume_up(TV& t);
bool volume_down(TV& t);
bool channel_up(TV& t);
bool channel_down(TV& t);
};
//TVController 函数定义
bool TVController::volume_up(TV& t)
{
if(t.volume < t.maxvol)
{
t.volume++;
return true;
}
return false;
}
bool TVController::volume_down(TV& t)
{
if(t.volume > t.minvol)
{
t.volume--;
return true;
}
return false;
}
bool TVController::channel_up(TV& t)
{
if(t.channel < t.maxchn)
{
t.channel ++;
return true;
}
return false;
}
bool TVController::channel_down(TV& t)
{
if(t.channel > t.minchn)
{
t.channel --;
return true;
}
return false;
}
int main(int argc,char* argv[]) {
TV mytv;
TVController ctl;
ctl.set_status(mytv);
ctl.volume_down(mytv);
ctl.channel_up(mytv);
mytv.print_tv_info(); return 0;
}

我们定义了一个TV类和TVController分别表示电视机和遥控器。在电视机类有一些常用的属性,如:开关、频道、音量。我们分别用on_off、volume、channel变量表示;在遥控器类(TVController)中我们声明了以下方法来控制电视类:

    //开关电视机
void set_status(TV& t){t.on_off = (t.on_off == t.on ? t.off : t.on);}
//增大音量
bool volume_up(TV& t);
//减小音量
bool volume_down(TV& t);
//加频道
bool channel_up(TV& t);
//减频道
bool channel_down(TV& t);

在这些方法中我们都需要访问TV类的成员变量,有两种方法,第一种是把TV类的成员变量都声明为public,但是这种做法显然不符合面向对象编程理念的。另一种是为每个属性增加set,get方法(例如:set_channel,get_channel),TVController类中对TV类的属性访问比较频繁,这样做代码会显得特别冗余,逻辑也不直观。

这时我们就需要將TVController类声明为TV类的友元类,具体做法是在TV类的声明中添加友元类的声明语句:

friend class TVController;

在main函数中我们定义TV类的对象mytv初始值为{on_off:1,volume:20,channel:5}和TVController 类的对象ctl,通过ctl对象的方法改变mytv对象的属性值。

执行程序输出:

on_off:0
volume:19
channel:4

C++中友元类使用场合的更多相关文章

  1. C++中的友元函数和友元类

    C++中的友元函数主要应用于以下场景: 友元函数 第一种场景 代码中有一个全局函数,该函数想要去访问某个类的成员变量(该类的成员变量是private的,且该类并未提供任何获取获取私有成员变量的publ ...

  2. C++雾中风景1:友元类与面向对象

    因为后续准备入职的公司都希望能转C++,所以最近也是按部就班的开始进行C++的学习.然后这个系列的文章打算探究C++的语言特性,也比较一下不同语言(如Java,Scala,Python,Go)之间的设 ...

  3. C++之友元机制(友元函数和友元类)

    一.为什么引入友元机制? 总的来说就是为了让非成员函数即普通函数或其他类可以访问类的私有成员,这确实破坏了类的封装性和数据的隐蔽性,但为什么要这么做呢? (c++ primer:尽管友元被授予从外部访 ...

  4. Objective-C中的类目,延展,协议

    Objective-C中的类目(Category),延展(Extension),协议(Protocol)这些名词看起来挺牛的,瞬间感觉OC好高大上.在其他OOP语言中就没见过这些名词,刚看到这三个名词 ...

  5. C++的友元类和友元函数实例

    #include <math.h> #include<iostream> using namespace std; class Point { public: Point(do ...

  6. 不可或缺 Windows Native (20) - C++: 友元函数, 友元类

    [源码下载] 不可或缺 Windows Native (20) - C++: 友元函数, 友元类 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 友元函数 友元类 示例演 ...

  7. C++学习12 友元函数和友元类

    友元函数和友元类在实际开发中较少使用,想快速学习C++的读者可以跳过本节. 一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有 ...

  8. YTU 2619: B 友元类-计算两点间距离

    2619: B 友元类-计算两点间距离 时间限制: 1 Sec  内存限制: 128 MB 提交: 469  解决: 252 题目描述 类Distance定义为类Point的友元类来实现计算两点之间距 ...

  9. C++:友元(非成员友元函数、成员友元函数、友元类)

    3.8  友元:友元函数和友元类 友元函数 :既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数,统称为友元函数.友元函数不是当前类的成员函数,而是独立于类的外部函数,但它可以访问该类所有的 ...

随机推荐

  1. py_One

    1.Python 标识符 在 Python 里,标识符由字母.数字.下划线组成. 在 Python 中,所有标识符可以包括英文.数字以及下划线(_),但不能以数字开头. Python 中的标识符是区分 ...

  2. Windows和Linux的编译理解

    Windows一般编译出来的x86的软件,就是只能在x86的系统上才能运行,同理,在x64系统上也是一样的道理. Linux利用gcc编译器编译,可以在Linux上面运行,但是想要在嵌入式系统上运行的 ...

  3. ASP.NET-缓存outputcache参数

    给Index加一个60秒的缓存,应该缓存在IIS服务器里面(我猜的) 只对变化的参数page不进行缓存,其他参数返回相同的内容 根据接受的语言的不同不进行缓存 设定缓存的位置 依赖于数据库变化的缓存 ...

  4. 洛谷—— P1855 榨取kkksc03

    https://www.luogu.org/problem/show?pid=1855 题目描述 洛谷2的团队功能是其他任何oj和工具难以达到的.借助洛谷强大的服务器资源,任何学校都可以在洛谷上零成本 ...

  5. 洛谷 P2758 编辑距离

    P2758 编辑距离 题目描述 设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1.删除一个字符: 2.插入一个字符: 3.将一个字符改为另一 ...

  6. [PYTHON]一个简单的单元測试框架

    近期尝试了一下TDD(測试驱动)的模式.感觉效果不错.在此总结一下,同学们假设有更好的办法,一定要告诉我:) 1. 每一个功能模块(文件),配一个单元測试模块. 以手头这个项目为样例:有LogCat. ...

  7. 三期_day02_数据库表设计和开发准备工作

    数据库脚本 drop table crm_user_info; drop table crm_work_customer_relation; drop table crm_business; drop ...

  8. Android sdk版本以及兼容性问题

    Android:minSdkVersion —— 此属性决定你的应用能兼容的最低的系统版本,一盘情况是必须设置此属性. android:targetSdkVersion —— 此属性说明你当前的应用是 ...

  9. java9新特性-5-Java的REPL工具: jShell命令

    1.官方Feature 222: jshell: The Java Shell (Read-Eval-Print Loop) 2.产生背景 像Python 和 Scala 之类的语言早就有交互式编程环 ...

  10. js相关禁止

    遇到网页上有精美图片或者精彩文字想保存时,通常大家都是选中目标后按鼠标右键,在弹出菜单中选择“图片另存为”或“复制”来达到我们的目的.但是,目前有许多网页都屏蔽了鼠标右键,那么用js如何实现禁止鼠标右 ...