在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. Go语言的前景分析

    本文为原创文章,转载注明出处,asdfasdfasdf 欢迎扫码关注公众号flysnow_org或者网站http://www.flysnow.org/,第一时间看后续精彩文章.觉得好的话,顺手分享到朋 ...

  2. C语言实现的minixml解析库入门教程

    minixml的中文说明手册:MiniXML中文文档.dochttp://wenku.baidu.com/view/25fd7d7f31b765ce050814f7.html xml源代码: < ...

  3. 可替代google的各种搜索引擎

    http://www.aol.com http://www.duckduckgo.com http://www.gfsoso.com http://www.googlestable.com  http ...

  4. bzoj1497【NOI2006】最大获利

    1497: [NOI2006]最大获利 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 3437  Solved: 1674 [id=1497" ...

  5. 腾讯之困,QQ与微信各有各的烦恼

    QQ渐渐在腾讯内部弱化 在PC时代,QQ是即时通讯领域当之无愧的王者.但在微信崛起后,手机QQ未来会被微信替代的判断喧嚣至上. 早在2012年就有传言腾讯在游戏领域開始去"娱乐化" ...

  6. Android 进程常驻(0)----MarsDaemon使用说明

    版权声明:本文为博主原创文章,未经博主允许不得转载. 这是一个轻量级的库,配置几行代码,就可以实现在Android上实现进程常驻,也就是在系统强杀下,以及360获取root权限下,clean mast ...

  7. angularjs作用域和函数调用

    <!DOCTYPE HTML> <html ng-app> <head> <meta http-equiv="Content-Type" ...

  8. Java中泛型的各种使用

    Java中的泛型的使用: 1.普通的泛型使用 在使用类的时候后面的<>中的类型就是我们确定的类型. public class MyClass1<T> {//此处定义的泛型是T ...

  9. Lumia 1520 IE mobile window.devicePixelRatio

    Lumia 1520 IE11 mobile -> window.devicePixelRatio = 2.217964285714286 Lumia 1520 UAP 环境 -> win ...

  10. 用LinkedList模拟Stack功能

    集合体系在Java中比较重要,整个集合体系是在JDK1.2版本后出现,Collection作为整个体系的顶层,拥有整个体系通用的功能.对于其下面的小弟,也是各有千秋.下面就一道面试题来看看Linked ...