【带头学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的专用模板⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️

谢     谢     老     板!老     板     大     气!

最近更新

  1. TCP协议是安全的吗?

    2023-12-12 19:28:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-12 19:28:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-12 19:28:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-12 19:28:02       18 阅读

热门阅读

  1. gitea仓库迁移

    2023-12-12 19:28:02       40 阅读
  2. 区块链:改变世界的技术

    2023-12-12 19:28:02       43 阅读
  3. Docker中安装并配置阿里巴巴的Sentinel控制台

    2023-12-12 19:28:02       41 阅读
  4. MySQL_6.MySQL常用创建语句

    2023-12-12 19:28:02       41 阅读
  5. 翻页新篇章:从Offset/Limit到游标分页的全面探索

    2023-12-12 19:28:02       37 阅读
  6. TypeScript 第四节:运算符

    2023-12-12 19:28:02       37 阅读
  7. 12、vue3(十二):用户管理页面搭建

    2023-12-12 19:28:02       37 阅读
  8. 定义一个存活态 HTTP 请求接口

    2023-12-12 19:28:02       37 阅读
  9. 12.11每日一题(备战蓝桥杯循环输出)

    2023-12-12 19:28:02       26 阅读
  10. 并发编程中的ConcurrentHashMap

    2023-12-12 19:28:02       37 阅读
  11. xtu oj 1327 字符矩阵

    2023-12-12 19:28:02       40 阅读
  12. Ubuntu(WSL)卸载与安装指定版本的 openssl

    2023-12-12 19:28:02       43 阅读
  13. 网络工程师【目录】

    2023-12-12 19:28:02       42 阅读