友元函数:不是类的成员函数,但是能够访问类的私有数据成员。

之前有个矛盾就是规定非成员函数不能直接访问类的私有数据,但是这会儿却可以,但那只是针对常规非成员函数而言,特殊的非成员函数就可以访问类的私有数据——友元函数

友元函数就是这么特殊,虽然在类中声明,却不是类的成员函数,这是因为加了前缀friend。

友元不仅包含函数,类也可以当友元,也就是友元类

友元类的所有方法都可以访问原始类的私有成员和保护成员。

也可以做更严格的限制,只将限定的成员函数指定为另一类的友元。

尽管友元被授予从外部访问类的私有部分的权限,但它们并不与面向对象的编程思想相违背。

接下来就是讨论友元类

假定要编写一个模拟电视机和遥控器的简单程序。

决定定义一个Tv类和一个Remote类,来分别表示电视机和遥控器。

很明显,这两个类之间应当存在某种关系,遥控器并非电视机,反之亦然,

但是遥控器却可以改变电视机的状态。这样的关系可以将Remote类作为Tv类的一个友元来实现。

友元类声明位置无关紧要,可以声明在公有、私有、保护部分;

定义一个电视机类,用一些状态成员来表示电视机:
开/关;
频道设置;
音量设置;
有线电视or天线调节模式;
TV调谐或A/V输入

tv.h文件,声明tv和remote的类

 #ifndef TV_H_
#define TV_H_ class Tv
{
public:
friend class Remote;
enum{Off, On};
enum{MinVal, MaxVal=};
enum{Antenna, Cable};
enum{TV,DVD}; Tv():state(s),volume(),maxchannel(mc),channel(),mode(Cable),input(TV){}
void onoff() {state=(state == On)?Off:On;}
bool ison() const {return state==On;}
bool volup();
bool voldown();
void chanup();
void chandown();
void set_mode() {mode=(mode == Antenna)?Cable:Antenna;}
void set_input() {input=(input == TV)?Cable:Antenna;}
void settings() const; //display all settings;
private:
int state; //on or off
int volume;
int maxchannel;
int channel; //current channel setting
int mode; //broadcast or cable
int inputs; //TV or DVD
}; class Remote //Remote方法以TV的对象引用作为参数,这表明遥控器必须针对特定的电视机
{
public:
int mode; //controls TV or DVD;
private:
Remote(int m=Tv::Tv): mode(m) {}
bool volup(Tv & t) {return t.volup();}
bool voldown(Tv & t) {return t.voldown();}
void onoff(Tv & t) {t.onoff();}
void chanup(Tv & t) {t.chanup();}
void chandown(Tv & t) {t.chandown();}
void set_chan(Tv & t, int c) {t.channel = c;}
void set_mode(Tv & t) {t.set_mode();}
void set_input(Tv & t) {t.set_input();}
};
#endif

tv.cpp

 #include <iostream>
#include "tv.h" bool Tv::volup()
{
if(volume<MaxVal)
{
volume++;
return true;
}
else
return false;
} bool Tv::voldown()
{
if(volume>MinVal)
{
volume--;
return true;
}
else
return false;
} void Tv:chanup()
{
if(channel<maxchannel)
channel++;
else
channel=;
} void Tv::chandown()
{
if(channel>)
channel--;
else
channel = maxchannel;
} void Tv::Settings() const
{
using std::cout;
using std::endl;
cout<<"TV is "<<(state==Off?"Off":"On")<<endl;
if(state == On)
{
cout<<"Volume setting = "<<volume<<endl;
cout<<"Channel setting = "<<channel<<endl;
cout<<"Mode = "<<(mode == Antenna? "antenna":"cable")<<endl;
cout<<"Input = "<<(mode == TV? "TV":"DVD")<<endl;
}
}

use_tv.cpp

 #include<iostream>
#include "tv.h" int main()
{
using std::cout;
Tv s42;
cout<<"Initial settings for 42\" TV:\n";
s42.settings();
s42.onoff();
s42.chanup();
cout<<"\nAdjusted settings for 42\" TV:\n";
s42.chanup();
cout<<"\nAdjusted settings for 42\" TV:\n";
s42.settings(); Remote grey; grey.set_chan(s42, );
grey.volup(s42);
grey.volup(s42);
cout<<"\n42\" settings after using remote:\n";
s42.settings(); Tv s58(Tv::On);
s58.set_mode();
grey.set_chan(s58,);
cout<<"\n58\" settings:\n";
s58.settings();
return ;
}

C++_友元1-友元类是什么的更多相关文章

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

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

  2. C++友元(友元函数、友元类和友元成员函数)

    友元(友元函数.友元类和友元成员函数) C++ 有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的.例如被重载的操作符,如输入或输出操作符,经常需要访问类的私 ...

  3. 12.3——类作用域,构造函数,友元,static类成员

    类作用域: (1)成员函数在类外定义时,因为函数体还有形参列表都出现在成员名之后,都是在类作用域内定义,所以不用加域作用符 来引用其他的成员. (2)函数的返回值不一定需要在类的作用域中,但是若是返回 ...

  4. cb02a_c++_数据结构_顺序容器_STL_list类_双向链表

    /*cb02a_c++_数据结构_顺序容器_STL_list类_双向链表实例化std::list对象在list开头插入元素在list末尾插入元素在list中间插入元素,插入时间恒定,非常快.数组:中间 ...

  5. cb01a_c++_数据结构_顺序容器_STL_deque类

    /*cb01a_c++_数据结构_顺序容器_STL_deque类deque是一个动态数组,比vector更加灵活.两者都属于动态数组deque与vector非常类似deque可以在数组开头和末尾插入和 ...

  6. C++拾遗(十三)友元和嵌套类

    友元类 使用友元的场合: 1.两个类既不是is-a关系也不是has-a关系,但是两个类之间又需要有联系,且一个类能访问另一个类的私有成员和保护成员. 2.一个类需要用到另外多个类的私有成员. C++p ...

  7. C++模板类内友元(友元函数,友元类)声明的三种情况

    根据<C++ Primer>第三版16.4节的叙述,C++类模板友元分为以下几种情况 1.非模板友元类或友元函数. 书上给了一个例子: class Foo{     void bar(); ...

  8. c++友元函数友元类

    友元函数和友元类的需要: 类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这 ...

  9. C++开发系列-友元函数 友元类

    友元函数 默认一个类的私有属性只能在该类的内部可以直接访问.友元函数申明在内的内部,实现在类的外部可以直接访问类的私有属性. class A1 { public: A1() { a1 = 100; a ...

随机推荐

  1. CURL以 POST 请求链接的方式 初始化一个cURL会话来获取一个网页

    /** *POST URL */ function posturl($URL,$data) { $ch = curl_init(); // 创建一个新cURL资源 curl_setopt($ch,CU ...

  2. WebFlux04 SpringBootWebFlux集成MongoDB之Windows版本、WebFlux实现CRUD、WebFlux实现JPA、参数校验

    1 下载并安装MongoDB 1.1 MongoDB官网 1.2 下载 solutions -> download center 1.3 安装 双击进入安装即可 1.3.1 安装时常见bug01 ...

  3. solr开发 小案例

    <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" ...

  4. ubuntu14.04 安装PCL

    博客转自:https://blog.csdn.net/dwj6336736/article/details/76674018 系统安装 sudo add-apt-repository ppa:v-la ...

  5. laravel中的attach and detach toggle method

    创建模型 post  and  user 以及 users , posts ,user_post(favorities)测试数据 在此可以看上一篇中的数据,本次测试数据利用的上一篇的数据.detach ...

  6. glib hash库GHashTable的使用实例

    前言 hash表是一种key-value访问的数据结构,hash表存储的数据能够很快捷和方便的去查询.在很多工程项目都需要使用到hash表来存储数据.对于hash表的详细说明这里就不进行阐述了,不了解 ...

  7. Alpha冲刺(二)

    Information: 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Details: 组员1(组长)柯奇豪 过去两天完成了哪些任务 学习并配置了ssm框架(用于前后端交 ...

  8. 关于同时查询父子名称的SQL查询语句的写法 id name parentId parentName .

    parentid是1就是id为1的公司的子公司 如图 查询出所有的信息后 由于我要呈现的是parentName 不是parentId所以想问下SQL语句怎么写 谢谢啦~~:) 解法: SELECT s ...

  9. APP压力稳定性测试

    转自:https://www.cnblogs.com/nuonuozhou/p/8643735.html 1.android系统自带monkey程序,模拟用户触摸屏幕,滑动track ball,按键等 ...

  10. .net List<T>

    List的几个方法 List=>List.Find()List.FindAll()List.Contains() List.ForEach()List.ConvertAll() 1. 先比较Fi ...