在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. Javascript系列——对象元素的数组去重实现

    概要 这是一篇记录文,记录数组操作对象去重的实现. 需求 有这样一个数组 [{ _id: 123, name: '张三' },{ _id: 124, name: '李四' },{ _id: 123, ...

  2. 紫书 习题 8-17 UVa 11536 (滑动窗口)

    这道题说连续子序列, 马上就想到滑动窗口. 注意窗口里面的元素中小于等于k的才是有效元素.记录窗口里面有效元素的个数, 满足了之后开始 缩短窗口, 如果左端点不是有效元素或者即使窗口中存在这个元素的个 ...

  3. 嵌入式(C)笔试题

    1 读程序段,回答问题 (a) int main(int argc,char *argv[]) { int c=9,d=0; c=c++%5; d=c; printf("d=%d\n&quo ...

  4. 【BZOJ 1503】[NOI2004]郁闷的出纳员

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 因为所有人工资同时递减. 所以可以设置一个变化值delta. 然后每个人的初始值为k 则把k-delta加入伸展树中. 会发现del ...

  5. Java 学习(11): 面向对象编程—继承(super,this)

    Java 继承 what: 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为.子类从它的父类中继承可访问的数据域和方法,也 ...

  6. Qt之QSpacerItem

    简述 QSpacerItem类为布局提供了一个空白区. 简述 比对 使用 效果 源码 效果 源码 比对 通常情况下,不需要直接使用这个类,Qt内建布局管理器在操控空白区时提供以下功能: 类 函数 QH ...

  7. lvs中dr模式配置脚本

    1 dr模式介绍 1.1 lvs的安装 安装具体解释:http://blog.csdn.net/CleverCode/article/details/50586957. 1.2 lvs模式 lvs有三 ...

  8. swift 给导航添加item,实现界面的跳转

    //给导航添加item         var rightItem = UIBarButtonItem(title: "First", style: UIBarButtonItem ...

  9. UI Framework-1: Aura Views

    Views Views is a user interface framework built on a type called, confusingly, View. Responsible for ...

  10. file_get_contents 无法采集 https 网站

    <?php echo file_get_contents("https://www.baidu.com"); ?> 运行以上代码会报以下错误: 再运行一次去看看!