【带头学C++】----- 九、类和对象 ---- 9.12 C++之友元函数(9.12.5---9.12.7)

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️创做不易,麻烦点个关注❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️

❤️❤️❤️❤️❤️❤️❤️❤️❤️文末有惊喜!献舞一支!❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️

目录

        补充上一节中声明的一个小细节,在你定义的时候,一定要使用域作用符去声明是哪个类对象的成员函数。

9.12.5 友元注意事项

9.12.6 友元的案例

9.12.7 设计动态数组类案例

 点赞👍  + 收藏👐 + 关注👌


        补充上一节中声明的一个小细节,在你定义的时候,一定要使用域作用符去声明是哪个类对象的成员函数。

9.12.5 友元注意事项

  1. 友元关系不能被继承。A类、B类是A类继承的子类,C类是A类的友元,但不一定是B的。除非你主动增加一个友元声明。
  2. 友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友。
  3. 友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友

9.12.6 友元的案例

案例qf:请编写电视机类,电视机有开机和关机状态,有音量,有频道,提供音量操作的方法,频道操作的方法。由于电视机只能逐一调整频道,不能指定频道,增加遥控类,遥控类除了拥有电视机已有的功能,再增加根据输入调台功能。

提示: 遥控器可作为电视机类的友元类

代码:

#include <iostream>

using namespace std;

class TV;
class RemoteControl{ //遥控器类,作为TV的友元
private:
    TV *p;
public:
    RemoteControl(TV *p);
    void turnOfforOn(void);
    void upVolume(void);
    void downVolume(void);
    void upChannel(void);
    void downChannel(void);
    void showTv(void);
    void setChannel(int channel);
};
class TV
{
    friend class RemoteControl;
    enum{OFF,ON};//枚举类型开关
    enum{minVol,maxVol=10};
    enum{minChan,maxChan=25};
private:
    int isOn; // 电视机的开关状态
    int volume; // 当前音量
    int channel; // 当前频道
public:
    TV(){
        isOn = OFF;
        volume = minVol;
        channel = minChan;
    }
    void turnOfforOn(void);
    void upVolume(void);
    void downVolume(void);
    void upChannel(void);
    void downChannel(void);
    void showTv(void);
};
int main()
{
    TV tvb;
    RemoteControl con(&tvb);
    con.turnOfforOn();
    con.setChannel(12);
    con.upVolume();
    con.downChannel();
    con.showTv();
    return 0;
}

void TV::turnOfforOn()
{
    isOn = (isOn == OFF?ON:OFF);   //condition ? if_true : if_false 三目运算
}

void TV::upVolume()
{
    if(volume == maxVol){
        cout << "音量已经最大了max"<<endl;
        return;
    }
    volume++;
}

void TV::downVolume()
{
    if(volume == minVol){
        cout << "音量已经最小了min"<<endl;
        return;
    }
    volume--;
}

void TV::upChannel()
{
    if(channel == maxChan){
        cout << "频道已经最大了"<<endl;
        return;
    }
    channel++;
}

void TV::downChannel()
{
    if(channel == minChan){
        cout << "频道已经最小了"<<endl;
        return;
    }
    channel--;
}

void TV::showTv()
{
    cout<<"当前电视机的状态:"<<(isOn == OFF?"关":"开")<<endl;
    cout<<"当前的音量是:"<<volume<<endl;
    cout<<"当前的频道是:"<<channel<<endl;
}


RemoteControl::RemoteControl(TV *p)
{
    this->p = p;//把友元类里面的私有类指针,赋值给传进来的TV对象
}

void RemoteControl::turnOfforOn()
{
    p->turnOfforOn();
}

void RemoteControl::upVolume()
{
    p->upVolume();
}

void RemoteControl::downVolume()
{
    p->downVolume();
}

void RemoteControl::upChannel()
{
    p->upChannel();
}

void RemoteControl::downChannel()
{
    p->downChannel();
}

void RemoteControl::showTv()
{
    p->showTv();
}

void RemoteControl::setChannel(int channel)
{
    if(channel >= p->minChan && channel<= p->maxChan){
        p->channel = channel;
    } else{
        cout<<"频道"<<channel<<"不在有效范围内"<<endl;
    }
}

结果:

9.12.7 设计动态数组类案例

        设计一个动态数组,可以实现一倍扩容,存放、读取某个位置的值、遍历数组、删除最后一个数组的的值,扩容的时候,可以实现2倍大小,并且对数组越界也做了相应处理。

代码:

main.cpp

#include "array.h"
#include "string.h"
using namespace std;

Array::Array()
{
    capacity = 5;
    size = 0;
    arr = new int[capacity];
    //空间清零
    memset(arr,0,sizeof(int)*capacity);
}

Array::Array(int capacity)
{
    this->capacity = capacity;
    size = 0;
    arr = new int[capacity];
    //空间清零
    memset(arr,0,sizeof(int)*capacity);
}

Array::Array(const Array &ob)
{
    capacity = ob.capacity;
    size = ob.size;

    //深拷贝
    arr = new int[capacity];
    memcpy_s(arr,sizeof(arr),ob.arr,sizeof (int)*capacity);
}

Array::~Array()
{
    if(arr != nullptr)
    {
        delete [] arr;
        arr = nullptr;
    }
}

int Array::getCapacity()
{
    return capacity;
}

int Array::getSize()
{
    return size;
}

void Array::printArray()
{
    for(int i = 0; i < size; i++)
    {
        cout<<arr[i]<<" ";
    }
    cout << endl;
}

void Array::pushBack(int elem)
{
    //判断的容器是否满
    if(size == capacity){
        //申请空间
        int *tmp = new int[2*capacity];
        memset(tmp,0,sizeof(int)*2*capacity);//将旧空间的内容 拷贝到新空间中
        memcpy(tmp,arr,size*sizeof(int));//释放旧空间
        delete [] arr;//让arr指向新空间
        arr = tmp;//更新容量
        capacity = 2*capacity;
    }
    arr[size] = elem;
    size++;
}

void Array::popBack()
{
    if(size == 0)
    {
        cout<<"容器为空"<<endl;
    }else{
        size--;
        arr[size]=0;
    }
}

int &Array::at(int pos)
{
    if(pos < 0 || pos >= size)
    {
        cout<<"数组越界"<<endl;
        exit(-1);
    }
    return arr[pos];
}

array.h

#ifndef ARRAY_H
#define ARRAY_H
#include <iostream>

class Array
{
public:
    Array();
    Array(int capacity);
    Array(const Array &ob);//拷贝构造
    ~Array();

private:
    int *arr;//存放数组首元素的地址
    int size;//数组大小
    int capacity;//数组容量
public:
    int getCapacity(void);
    int getSize(void);
    void printArray(void);
    //尾部插入数据
    void pushBack(int elem);
    //尾部删除元素
    void popBack(void);
    //查询当前位置
    int& at(int pos);
};

#endif // ARRAY_H

array.cpp

#include "array.h"
#include "string.h"
using namespace std;

Array::Array()
{
    capacity = 5;
    size = 0;
    arr = new int[capacity];
    //空间清零
    memset(arr,0,sizeof(int)*capacity);
}

Array::Array(int capacity)
{
    this->capacity = capacity;
    size = 0;
    arr = new int[capacity];
    //空间清零
    memset(arr,0,sizeof(int)*capacity);
}

Array::Array(const Array &ob)
{
    capacity = ob.capacity;
    size = ob.size;

    //深拷贝
    arr = new int[capacity];
    memcpy_s(arr,sizeof(arr),ob.arr,sizeof (int)*capacity);
}

Array::~Array()
{
    if(arr != nullptr)
    {
        delete [] arr;
        arr = nullptr;
    }
}

int Array::getCapacity()
{
    return capacity;
}

int Array::getSize()
{
    return size;
}

void Array::printArray()
{
    for(int i = 0; i < size; i++)
    {
        cout<<arr[i]<<" ";
    }
    cout << endl;
}

void Array::pushBack(int elem)
{
    //判断的容器是否满
    if(size == capacity){
        //申请空间
        int *tmp = new int[2*capacity];
        memset(tmp,0,sizeof(int)*2*capacity);//将旧空间的内容 拷贝到新空间中
        memcpy(tmp,arr,size*sizeof(int));//释放旧空间
        delete [] arr;//让arr指向新空间
        arr = tmp;//更新容量
        capacity = 2*capacity;
    }
    arr[size] = elem;
    size++;
}

void Array::popBack()
{
    if(size == 0)
    {
        cout<<"容器为空"<<endl;
    }else{
        size--;
        arr[size]=0;
    }
}

int &Array::at(int pos)
{
    if(pos < 0 || pos >= size)
    {
        cout<<"数组越界"<<endl;
        exit(-1);
    }
    return arr[pos];
}

 

 点赞👍  + 收藏👐 + 关注👌

❤️您的支持❤️是我最大的动力❤️相互学习❤️共同进步❤️一起搞钱❤️动动发财的小手❤️

  ⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️十星好评,Erike的专用模板⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️

谢     谢     老     板!老     板     大     气!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/246415.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes 容器编排 -- 1

前言 知识扩展 早在 2015 年 5 月&#xff0c;Kubernetes 在 Google 上的搜索热度就已经超过了 Mesos 和 Docker Swarm&#xff0c;从那儿之后更是一路飙升&#xff0c;将对手甩开了十几条街,容器编排引擎领域的三足鼎立时代结束。 目前&#xff0c;AWS、Azure、Google、阿里…

Vulnhub-DC-3 靶机复现完整过程

啰嗦两句&#xff1a; 提权之前完成是一个月前做的&#xff0c;当时在提权处出了点问题就搁置了&#xff0c;今天才完成&#xff0c;所以IP地址可能会会有变化 注意&#xff1a;后续出现的IP地址为192.168.200.55同样是靶机IP地址&#xff0c;若本文能有帮助到你的地方&#xf…

k8s中的Pod

目录 1.1 创建一个pod 1.2 pod是如何被创建的 1.3 创建一个单容器pod 1.4 创建一个多容器pod 1.4.1 配置节点标签 1.5 Pod容器的交互 1.5.1 创建pod&#xff0c;并做本地解析 1.5.2 pod共享进程 1.5.2 pod共用宿主机namespace Pod 是可以在 Kubernetes 中创建和管理的、…

Redis设计与实现之字典

目录 一、字典 1、 字典的应用 实现数据库键空间 用作Hash类型键的其中一种底层实现 2、字典的实现 哈希表实现 哈希算法 3、创建新字典 4、添加键值对到字典 5、添加新元素到空白字典 6、添加新键值对时发生碰撞处理 7、添加新键值对时触发了 rehash操作 Note:什么…

Java 基础学习(九)API概述、Object、String、正则表达式

1 API概述 1.1 API概述 1.1.1 什么是API API(Application Programming Interface)&#xff0c;意为&#xff1a;应用程序接口。API就是已经写好的的程序或功能&#xff0c;程序要需要时可以直接调用&#xff0c;无需再次编写。 API可以大致分为如下几类&#xff1a; 编程语…

【笔试强化】Day 2

文章目录 一、选择1.2.&#xff08;写错&#xff09;3.4.5.6.&#xff08;不会&#xff09;7.&#xff08;不清晰&#xff09;8. &#xff08;不会&#xff09;9.10.&#xff08;写错&#xff09; 二、编程1. 排序子序列解法&#xff1a;代码&#xff1a; 2. 倒置字符串解法&am…

STM32--中断使用(超详细!)

写在前面&#xff1a;前面的学习中&#xff0c;我们接触了STM32的第一个外设GPIO&#xff0c;这也是最常用的一个外设&#xff1b;而除了GPIO外&#xff0c;中断也是一个十分重要且常用的外设&#xff1b;只有掌握了中断&#xff0c;再处理程序时才能掌握好解决实际问题的逻辑思…

MyBatis之逆向工程

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

IT圈茶余饭后的“鄙视链”

哈哈&#xff0c;IT圈的鄙视链&#xff0c;简直就是一出情感大戏&#xff01;这个圈子里的人们总是忍不住要互相比较&#xff0c;互相鄙视&#xff0c;仿佛这是一场刺激的游戏&#xff0c;每个人都想要站在鄙视链的最顶端&#xff0c;成为那个最牛逼的存在。 首先&#xff0c;…

uniapp开发项目注意事项

uniapp创建项目用HBuilderX创建或者用脚手架命令创建都可以vue文件渲染h5&#xff0c;小程序很好nvue文件渲染原生app更好&#xff0c;注意nvue文件css的一些局限性&#xff0c;简称坑死人nvue所支持的通用样式已在本文档中全部列出&#xff0c;一些组件可能有自定义样式&#…

Docker网络模式:深度理解与容器网络配置

Docker 的网络模式是容器化应用中一个关键而复杂的方面。本文将深入讨论 Docker 的网络模式&#xff0c;包括基本概念、常用网络模式以及高级网络配置&#xff0c;并通过更为丰富和实际的示例代码&#xff0c;帮助读者全面掌握如何理解和配置容器网络。 Docker网络基础 1 Doc…

Pr自动从视频脚本剪辑视频FirstCut插件免费下载

FirstCut 插件将自动从视频脚本中剪辑视频&#xff0c;在例如新闻、采访、自媒体视频等带有配音或字幕内容的视频制作中提高了粗剪效率。 使用 FirstCut&#xff0c;大大缩短了粗剪的时间&#xff0c;而不是转到每个视频文件并找到 IN 点和 OUT 点&#xff0c;然后将其插入到序…

ubuntu install sqlmap

refer: https://github.com/sqlmapproject/sqlmap 安装sqlmap&#xff0c;可以直接使用git 克隆整个sqlmap项目&#xff1a; git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev 2.然后进入sqlmap-dev&#xff0c;使用命令&#xff1a; python s…

改进了编排控制并增强了推理的可视性,Agents for Amazon Bedrock 现已上市

七月份的时候&#xff0c;我们推出了 Agents for Amazon Bedrock 预览版。如今&#xff0c;Agents for Amazon Bedrock 全面上市。 Agents for Amazon Bedrock 通过编排多步任务&#xff0c;有助于您加速生成人工智能 &#xff08;AI&#xff09; 应用程序的开发。代理使用基础…

@德人合科技——天锐绿盾|电脑文件防止泄密|文件、文档、图纸、源代码等透明加密保护,防泄密软件系统

德人合科技——天锐绿盾提供了一种企业办公电脑文件防止泄密的解决方案&#xff0c;该方案对文件、文档、设计图纸、源代码等进行了透明加密保护。 pc访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 透明加密是一种保护文…

Qt 表格相关API

1.文本框 限制输入数据类型&#xff08;如仅英文&#xff09; QValidator* validator new QRegExpValidator(QRegExp("[a-zA-Z]"), lineText); // 创建正则表达式验证器lineText->setValidator(validator); // 将验证器设置给 QLineEdit QLineEdit&#xff1a;单…

Python接口自动化 —— Json 数据处理实战(详解)

简介   上一篇说了关于json数据处理&#xff0c;是为了断言方便&#xff0c;这篇就带各位小伙伴实战一下。首先捋一下思路&#xff0c;然后根据思路一步一步的去实现和实战&#xff0c;不要一开始就盲目的动手和无头苍蝇一样到处乱撞&#xff0c;撞得头破血流后而放弃了。不仅…

百元买百鸡问题

#include<stdio.h> void printf(){int z, i, j, t 0;for (i 0; i <20; i){for (j 0; j < 33; j){z 100 - i - j;if ((z % 3 0) && (i * 5 j * 3 z / 3 100)){t;printf("公鸡的个数%d 母鸡的个数%d 小鸡个数%d", i, j, z);printf(&quo…

《使用ThinkPHP6开发项目》 - ThinkPHP6使用JWT验证登录Token

《使用ThinkPHP6开发项目》 - 登录接口三【表单验证】-CSDN博客 上面说到的使用 JWT生成Token&#xff0c;现在来说下如何使用JWT验证登录Token 1&#xff09;在app\common.php文件中引入JWT验证文件 #app\common.php use Firebase\JWT\Key; use Firebase\JWT\SignatureInva…

从开源项目中学习如何自定义 Spring Boot Starter 小组件

前言 今天参考的开源组件Graceful Response——Spring Boot接口优雅响应处理器。 具体用法可以参考github以及官方文档。 基本使用 引入Graceful Response组件 项目中直接引入如下maven依赖&#xff0c;即可使用其相关功能。 <dependency><groupId>com.feiniaoji…