C++ Primer Plus 学习笔记 第十五章 友元类 友元成员函数 其他友元关系 共同的友元 嵌套类

本文主要是介绍C++ Primer Plus 学习笔记 第十五章 友元类 友元成员函数 其他友元关系 共同的友元 嵌套类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

与友元函数类似。

代码:

tv.h

#ifndef TV_H_
#define TV_H_class Tv
{public:
// 这就是友元类的写法friend class Remote;enum {Off, On};enum {MinVal, MaxVal = 20};enum {Antenna, Cable};enum {TV, DVD};Tv(int s = Off, int mc = 125) : state(s), volume(5),maxchannel(mc), channel(2), mode(Cable), input(TV) {}void onoff() {state = (state == On) ? Off : On;}bool ison() {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)? DVD : TV;}void settings() const;private:int state;int volume;int maxchannel;int channel;int mode;int input;
};class Remote
{private:int mode;public:Remote(int m = Tv::TV) : mode(m){}bool volup(Tv & t) {return t.volup();}bool voldown(Tv & t) {return t.voldown();}void cnoff(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

这里面那么多的函数 只有1个函数涉及到了友元,那能不能让特定的成员函数成为友元呢? 可以:

class Tv
{friend void Remote::set_chan(Tv & t, int c);.....
};

光这样写还不行  要让编译器事先知道Remote是啥 但是, 又有一个问题 Remote中有涉及到了Tv类,那也要事先让编译器知道Tv类是啥; 这就蛋疼了,咋搞?

使用前向声明

class Tv;

class Remote {....};

class Tv{...};

这样排列后还是有一个问题,就是Remote中很多函数时内联函数,也就是说提前调用了Tv类的函数。那编译器依然找不到对应的函数。咋办?

Remote类中涉及调用Tv类的成员的部分 放到Tv类定义的代码段后面写。就可以了

上示例吧:

#ifndef TV_H_
#define TV_H_// 先声明
class Tv;class Remote
{public:enum {Off, On};enum {MinVal, MaxVal = 20};enum {Antenna, Cable};enum {TV, DVD};private:int mode;public:Remote(int m = TV) : mode(m){}bool volup(Tv & t);bool voldown(Tv & t);void cnoff(Tv & t);void chanup(Tv & t);void chandown(Tv & t);void set_chan(Tv & t, int c);void set_mode(Tv & t);void set_input(Tv & t);
};// 再详细声明
class Tv
{public:
// 特定友元函数friend void Remote::set_chan(Tv & t, int c);enum {Off, On};enum {MinVal, MaxVal = 20};enum {Antenna, Cable};enum {TV, DVD};Tv(int s = Off, int mc = 125) : state(s), volume(5),maxchannel(mc), channel(2), mode(Cable), input(TV) {}void onoff() {state = (state == On) ? Off : On;}bool ison() {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)? DVD : TV;}void settings() const;private:int state;int volume;int maxchannel;int channel;int mode;int input;
};// 最后定义内联函数
inline bool Remote::volup(Tv & t) {return t.volup();}
inline bool Remote::voldown(Tv & t) {return t.voldown();}
inline void Remote::cnoff(Tv & t) {t.onoff();}
inline void Remote::chanup(Tv & t) {t.chanup();}
inline void Remote::chandown(Tv & t) {t.chandown();}
inline void Remote::set_mode(Tv & t) {t.set_mode();}
inline void Remote::set_input(Tv & t) {t.set_input();}
inline void Remote::set_chan(Tv & t, int c) {t.channel = c;}
#endif

其他友元关系:

如果Tv类成为Remote的友元。那有一点要注意  在Tv类中调用了Remote类的相关成员或成员函数  一定要写在Remote类详细声明的后面。(先来后到 不然编译器无法识别Remote是啥玩意儿,这个跟刚才那个友元成员函数是一个情况)

共同的友元

这个没啥内容 就是弄一个内联函数 然后成为两个或者多个类的友元函数就是了

这里有句话很关键

嵌套类

嵌套类定义格式

嵌套类的作用域:

访问控制:

模板中的嵌套

其实就是内部类啦

形象的表示就是人的器官 也是类 但是是在人这个类的内部

上代码:

queuetp.h

#ifndef QUEUETP_H_
#define QUEUETP_H_template<class Item>
class QueueTP
{private:enum {Q_SIZE = 10};class Node{public:Item item;Node * next;Node(const Item & i) : item(i), next(0) {}};Node * front;Node * rear;int items;const int qsize;QueueTP(const QueueTP & q) : qsize(0) {}QueueTP & operator=(const QueueTP & q) {return *this;}public:QueueTP(int qs = Q_SIZE);~QueueTP();bool isempty() const{return items == 0;}bool isfull() const{return items == qsize;}int queuecount() const{return items;}bool enqueue(const Item & item);bool dequeue(Item & item);
};template<class Item>
QueueTP<Item>::QueueTP(int qs) : qsize(qs)
{front = rear = 0;items = 0;
}template<class Item>
QueueTP<Item>::~QueueTP()
{Node * temp;while(front != 0){temp = front;front = front-> next;delete temp;}
}template<class Item>
bool QueueTP<Item>::enqueue(const Item & item)
{if (isfull())return false;Node * add = new Node(item);items++;if (front == 0)front = add;elserear->next = add;rear = add;return true;
}template<class Item>
bool QueueTP<Item>::dequeue(Item & item)
{if (front == 0)return false;item = front->item;items--;Node * temp = front;front = front -> next;delete temp;if (items == 0)rear = 0;return true;
}#endif

nested.cpp

#include <iostream>
#include "queuetp.h"int main()
{using std::string;using std::cin;using std::cout;QueueTP<string> cs(5);string temp;while(!cs.isfull()){cout << "Please enter your name. You will be ""served in the order of arrival.\n""name: ";getline(cin, temp);cs.enqueue(temp);}cout << "The queue is full. Processing begins!\n";while (!cs.isempty()){cs.dequeue(temp);cout << "Now processing " << temp << "...\n";}return 0;
}

完结

这篇关于C++ Primer Plus 学习笔记 第十五章 友元类 友元成员函数 其他友元关系 共同的友元 嵌套类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/639633

相关文章

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

VSCode中C/C++编码乱码问题的两种解决方法

《VSCode中C/C++编码乱码问题的两种解决方法》在中国地区,Windows系统中的cmd和PowerShell默认编码是GBK,但VSCode默认使用UTF-8编码,这种编码不一致会导致在VSC... 目录问题方法一:通过 Code Runner 插件调整编码配置步骤方法二:在 PowerShell

mybatis-plus分页无效问题解决

《mybatis-plus分页无效问题解决》本文主要介绍了mybatis-plus分页无效问题解决,原因是配置分页插件的版本问题,旧版本和新版本的MyBatis-Plus需要不同的分页配置,感兴趣的可... 昨天在做一www.chinasem.cn个新项目使用myBATis-plus分页一直失败,后来经过多方

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

C/C++随机数生成的五种方法

《C/C++随机数生成的五种方法》C++作为一种古老的编程语言,其随机数生成的方法已经经历了多次的变革,早期的C++版本使用的是rand()函数和RAND_MAX常量,这种方法虽然简单,但并不总是提供... 目录C/C++ 随机数生成方法1. 使用 rand() 和 srand()2. 使用 <random

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

MyBatis-Plus中静态工具Db的多种用法及实例分析

《MyBatis-Plus中静态工具Db的多种用法及实例分析》本文将详细讲解MyBatis-Plus中静态工具Db的各种用法,并结合具体案例进行演示和说明,具有很好的参考价值,希望对大家有所帮助,如有... 目录MyBATis-Plus中静态工具Db的多种用法及实例案例背景使用静态工具Db进行数据库操作插入

MySQL中COALESCE函数示例详解

《MySQL中COALESCE函数示例详解》COALESCE是一个功能强大且常用的SQL函数,主要用来处理NULL值和实现灵活的值选择策略,能够使查询逻辑更清晰、简洁,:本文主要介绍MySQL中C... 目录语法示例1. 替换 NULL 值2. 用于字段默认值3. 多列优先级4. 结合聚合函数注意事项总结C