在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. 让div垂直居中

    参考链接:https://www.cnblogs.com/softwarefang/p/6095806.html 以前我的方法总是比较粗暴,纯粹通过margin来实现,这个方法的缺点不仅在于需要多次微 ...

  2. Docker学习总结(8)——利用Docker开启持续交付之路

    持续交付即Continuous Delivery,简称CD,随着DevOps的流行正越来越被传统企业所重视.持续交付讲求以短周期.小细粒度,自动化的方式频繁的交付软件,在这个过 程中要求开发.测试.用 ...

  3. OO问题

    设计一个在线的酒店预订系统,并且可以通过城市搜索出来 解决办法: Main Class: User Room Hotel Booking Adress Enums : 房间的状态和类型 public ...

  4. Flex 远程视频监控观看端新版

    第一个版本号仅仅做了预览这一块 http://blog.csdn.net/songanling/article/details/38306037,后面老板看了认为色调太暗.看得不舒服,然后就開始又一次 ...

  5. mysql-幻读及其例子

    第一步建表并插入5条记录:  接下来我们看下大部分mysql所说的幻读现象: 事务1(开启事务查询发现没有记录6准备插入):  事务2(开启事务,发现没有记录6插入,并提交事务):  事务1:查询发现 ...

  6. GridView中使用CheckBox

    asp.net中checkbox是向server提交时才干触发事件 把该控件的autopostback设置为true.才干响应事件  protected void Checkbox_CheckedCh ...

  7. iOS开发-sqlite3使用

    SQLite3使用 SQLite简介 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中. SQLite3 在XCode工程中,打开targets,在B ...

  8. python判断一个单词是否为有效的英文单词?——三种方法

    For (much) more power and flexibility, use a dedicated spellchecking library like PyEnchant. There's ...

  9. git的学习笔记整理

    Git学习较好的网址:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001373 ...

  10. struts2入门(搭建环境、配置、示例)

    转自:https://blog.csdn.net/u012862311/article/details/53412716 1.下载Struts2的jar包 下载地址:http://archive.ap ...