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

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

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

目录

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

[9.12.5 友元注意事项](#9.12.5 友元注意事项)

[9.12.6 友元的案例](#9.12.6 友元的案例)

[9.12.7 设计动态数组类案例](#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:请编写电视机类,电视机有开机和关机状态,有音量,有频道,提供音量操作的方法,频道操作的方法。由于电视机只能逐一调整频道,不能指定频道,增加遥控类,遥控类除了拥有电视机已有的功能,再增加根据输入调台功能。

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

代码:

cpp 复制代码
#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

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

cpp 复制代码
#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

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

谢 谢 老 板!老 板 大 气!

相关推荐
Wacanda1 小时前
【日志】盛趣面试
笔记
深情汤姆1 小时前
C++ 红黑树
数据结构·c++
skaiuijing1 小时前
Sparrow系列拓展篇:消息队列和互斥锁等IPC机制的设计
c语言·开发语言·算法·操作系统·arm
绵绵细雨中的乡音3 小时前
C++第28课-布隆过滤器的介绍
c++·哈希算法
Simulink_3 小时前
ROS学习笔记15——Xacro
linux·笔记·学习·机器人·ros
雯0609~3 小时前
c#:winform调用bartender实现打印(学习整理笔记)
开发语言·c#
C++忠实粉丝3 小时前
计算机网络socket编程(5)_TCP网络编程实现echo_server
网络·c++·网络协议·tcp/ip·计算机网络·算法
2301_775281194 小时前
当日本人说「お疲れ様」时,该怎么回?柯桥日语培训零基础学习
学习
E___V___E4 小时前
CSAPP学习
学习
胜天半子_王二_王半仙4 小时前
c++源码阅读__smart_ptr__正文阅读
开发语言·c++·开源