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

news2024/12/23 11:10:39

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

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

目录

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

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的专用模板⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️

谢     谢     老     板!老     板     大     气!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软文营销怎么做才能“人性化”,媒介盒子有妙招

软文营销已经成为品牌宣传的重要方式之一&#xff0c;想要做好软文营销&#xff0c;则要避免高高在上的宣传&#xff0c;围绕用户心理&#xff0c;打造人性化的内容。今天媒介盒子就来和大家聊聊软文营销怎么做才能人性化。 一、以情感驱动用户 形成用户印象所需要的时间是1/1…

Netflix Mac(奈飞客户端)激活版软件介绍

Netflix Mac(奈飞客户端)是一款流行的视频播放软件&#xff0c;专为Mac用户设计。它提供了大量的高质量电影、电视剧、纪录片和动画片资源&#xff0c;让用户可以随时随地观看自己喜欢的内容。 首先&#xff0c;Netflix Mac(奈飞客户端)以其简洁直观的用户界面而闻名。用户可以…

用FPGA实现四通道、全频率 GNSS RF 接收器-用于卫星的精确定位

用FPGA实现四通道、全频率 GNSS RF 接收器-用于卫星的精确定位 概念 全球导航卫星系统&#xff08;英文&#xff1a;Global Navigation Satellite System&#xff0c;GNSS &#xff09;&#xff0c;又称全球卫星导航系统&#xff0c;是能在地球表面或近地空间的任何地点为用户提…

阿木实验室普罗米修斯项目环境配置

引言 普罗米修斯项目其实只是个大ROS功能包&#xff0c; 里面每个模块就是每个ROS功能包&#xff0c;比如控制模块&#xff0c;视觉模块等等。对PX4配置的与这个一样&#xff0c;另外他是使用自己的P系列无人机&#xff08;我个人是&#xff30;450&#xff09;&#xff0c;所…

LAMP的搭建

LAMP概述 LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整套系统和相关软件&#xff0c;能够提供动态Web站点服务及其应用开发环境。LAMP是一个缩写词&#xff0c;具体包括Linux操作系统、Apache网站服务器、MySQL数据库服务器、PHP&#xff08;或…

[学习笔记]在CentOS7中用Docker方式安装Jenkins

文章目录 原理&#xff1a;创建Docker网桥网络安装DinD创建镜像构建镜像运行容器 原理&#xff1a; Docker in Docker &#xff08;以下简称 DinD&#xff09;可以在 Container 中直接运行一个 Docker Daemon &#xff0c;然后使用 Container 中的 Docker CLI 工具操作容器。其…

做数据分析为何要学统计学(6)——什么问题适合使用t检验?

t检验&#xff08;Students t test&#xff09;&#xff0c;主要依靠总体正态分布的小样本&#xff08;例如n < 30&#xff09;对总体均值水平进行差异性判断。 t检验要求样本不能超过两组&#xff0c;且每组样本总体服从正态分布&#xff08;对于三组以上样本的&#xff0…

apt-get update失败

一、先验证是否有网络 rootlocalhost:~# ping www.baidu.com ping: www.baidu.com: Temporary failure in name resolution rootlocalhost:~# 说明没有网&#xff0c;参考&#xff1a;https://blog.csdn.net/qq_43445867/article/details/132384031 sudo vim /etc/resolv.con…

windows如何解决端口冲突(实用篇)

在项目设计中&#xff0c;环境配置成功点击运行瞬间&#xff0c;一大堆红爆出&#xff0c;8080端口占用&#xff0c;这个是很烦人的。。。 解决方式&#xff1a; 笨方法&#xff1a;一、查看所有端口实用情况&#xff08;挨个扫&#xff09; 按住【WINR】快捷键打开运行输入…

报表控件FastReport .NET v2024功能演示—更改图图片形状

报表生成器FastReport .NET 是适用于.NET Core 3&#xff0c;ASP.NET&#xff0c;MVC和Windows窗体的全功能报告库。使用FastReport .NET&#xff0c;您可以创建独立于应用程序的.NET报告。 FastReport .net下载&#xff08;qun&#xff1a;585577353&#xff09;https://www.e…

靠着这份280页的前端面试指南,拿下了字节跳动offer

笔者是在今年秋招面试的头条教育线&#xff0c;顺利拿到了offer&#xff0c;把还记得的东西写下来&#xff0c;供大家参考一下。 一面 tcp 和 udp 的区别和使用场景&#xff1f;quic 基于 udp 怎么保证可靠性&#xff1f;讲一下同源策略和跨域方案&#xff1f;CORS 的几个头部…

AutoAnimate动画库,仅需一行代码

插件官网,支持react,vue AutoAnimate - Add motion to your apps with a single line of code 自动加动画原理 AutoAnimate 加动画的原理也很简单&#xff0c;监听绑定的 DOM 节点里 DOM 结构变化&#xff0c;自动添加对应的过渡动画&#xff1a; 增加子节点 > 渐入动画…

智能检测/摄像头监控系统EasyCVR无法启动进程是什么原因?如何解决?

国标GB28181智慧安防平台EasyCVR支持高清视频的接入和传输、分发&#xff0c;平台采用了开放式的网络结构&#xff0c;提供实时远程视频监控、录像回放与存储等功能。视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c;也能支持…

数据库系统 --- 关系模型

一、关系模型的数据结构以及形式化定义 1.关系 域&#xff1a;一组具有相同数据结构的值的集合。 笛卡尔积&#xff1a;域上的一种集合运算。多个集合做笛卡尔积的结果是每个集合取一个元素组合得到的一个新的集合。 域的基数&#xff1a;一个域上允许的不同取值的个数。 关系&…

【数仓理论】

一、数仓建模方法论 1.1 ER模型&#xff08;Entity Relationship、实体关系模型、范式模型&#xff09; ER模型是Bill Inmon提出的一种建模方法&#xff0c;实体关系模型将复杂的数据抽象为两个概念 ---- 实体和关系 该模型在范式理论上符合3NF&#xff0c;这种模型目的是减少…

VTK学习(入门级教程,包括安装和使用)~持续更新中

说明&#xff1a;研究QTVTK有段时间了&#xff0c;准备把学到的东西分享给大家&#xff0c;这篇博客以VSQTVTK为主进行展开学习的。 VTK学习 VTK安装和使用教程VTK入门级教程设计界面vtkStudy.ui的操作vtkStudy.h头文件说明完整代码 vtkStudy.cpp绘制球体绘制长方体绘制圆柱绘制…

wordpress多語言插件Polylang與GTranslate會有衝突

wordpress多語言插件Polylang與GTranslate會有衝突,會導致分頁顯示不完整&#xff0c;需要禁用或卸載其中一個 分頁顯示才會沒問題 GTranslate必須要先按一種語言編輯好你要發佈網站&#xff0c;GTranslate這種語言為基礎去翻譯出來&#xff0c;其實內裡是套用了google 翻譯的…

第二证券:结构性行情或将延续 泛科技有望继续走强

展望未来&#xff0c;当时已进入重要的方针窗口期&#xff0c;能否有超预期的新方针推出是改变商场的要害。但复盘2023年的行情来看&#xff0c;过早买卖方针预期的成功率并不高&#xff0c;因而主张该方位以防御性资产为主&#xff0c;高股息资产从本年9月份至今现已调整了2个…

ubuntu dns 相关

查看dns配置 systemd-resolve --status 修改dns vim /etc/resolv.conf sudo apt install traceroute 追踪 traceroute www.baidu.com

windows下docker环境安装

开启硬件虚拟化技术 win10中开启 Hyper-V Win10 下是否开启硬件虚拟化技术&#xff0c;在控制面板&#xff0c;启用 window 功能&#xff0c;找到 Hyper-V 选项&#xff0c;点勾选确认。如图&#xff1a; Windows 11 家庭中文版新增 Hyper-V选项 注意以下的解决方案来自win1…