C++积累02_隔定时长放炮问题的OOP解决

今天又来写博客啦!
昨天使用了面向过程的思维解决了隔定时长放炮问题。但今天又有了一些其他想法:

  • 正是想到c++这个语言可以使用面向对象的编程,所以我才会想到,昨天的这个隔定时长放炮问题里面,可以如何应用OOP呢?
  • 看了看,昨天的程序里面最多的是对数组的操作,其实可以把这些操作封装到类中。
  • 同时也可以学习到多文件编程的好处。
  • 也就算是复习了一遍OOP编程的知识点~

想看昨天的面向过程思维的,点击:萌新的c++积累01_几个人各隔一定时长放炮问题

题目如下

甲、乙、丙三人同时放鞭炮, 甲每隔 a 秒放一个, 乙每隔 b 秒放一个, 丙每隔 c 秒放一个, 他们各自都放 d 个。对给定的 a、b、c 和 d(a,b,c>0) (d是正整数) 求能听到多少声鞭炮响。 假设两个响声相差小于 0.001秒时,人无法区分。

本解决方法的思路

  • 正是因为昨天那个程序里极多的操作都是操作数组,为了操作数组有着各式循环与条件判断,煞是复杂。所以,可以考虑把所有的操作都封装到一个类中,把各操作定义为类的成员函数。
  • 既可以采用多文件的形式来定义类、定义类的成员函数、写主程序,
  • 也可以采用单文件的形式,把所有的都写到一起。

首先,定义类

类的定义可以与主程序放在一个cpp文件中,也可以新建一个头文件(*.h)来存放类的定义。
代码如下:

#pragma once
//这个是为了避免一个文件被#include多次而使用的
class WVector
{
private:
    int* stArray;//定义一个指针变量,存放数组的首地址

public:
    int Count = 0;//这个变量用来计数,记录这个数组中数字的个数

public:
    WVector();//默认构造函数
    WVector(int size);//带数组大小的构造函数,具体定义后面会写
    void SetSize(int size);//用c++老师的话来说,“setter”,用来申请一个动态数组
    ~WVector();//析构函数
    bool Add(int item);//用来往数组里添加函数
    void Update(int index, int item);//用来更新某一个位置上的数据
    int Get(int index);//用来获得某一个位置上的数据
    bool Contain(int item);//用来检测item是否已经存在于数组中
};

然后,定义类的成员函数

类的成员函数的定义,可以与主函数一起放在一个.cpp文件中,也可以新建一个.cpp文件专门用来定义,IDE会把不同文件里的这些定义串起来的。
代码如下(为了方便观看,把代码的解释以注释的形式放入):

#include "WVector.h"
//	这里如果类的定义是在.h头文件里声明的话
//	这个.cpp文件中必须先 #include"***.h"

WVector::WVector(int size)
{
    SetSize(size);
    //构造函数的原理与setter的原理是一样的,所以可以代码复用一下子
}

WVector::WVector()
{
    stArray = nullptr;
    //先把指针变量赋值成NULL,方便后续使用,也避免内存泄漏
}

void WVector::SetSize(int size)//设计setter
{
    if (stArray != nullptr)
    {
        delete[] stArray;
        stArray = nullptr;
    }

    stArray = new int[size];

    for (int i = 0; i < size; i++)
        stArray[i] = 0;
        
//	这里上面的那个if语句表示,如果stArray变量的值不是NULL的话,
//	就把之前的删除掉重新赋值,这样如果多次使用setter的话也可以避免内存泄漏。
//	千万注意!!!!!!!!
}

WVector::~WVector()
{
    delete[] stArray;
    stArray = nullptr;
//	析构函数清除掉申请的动态数组并且指针置为NULL自不必说!!!
}

bool WVector::Add(int item)
{
    if (stArray != nullptr)
    {
        stArray[Count] = item;
        Count++;//下标+1
        return true;
    }
    return false;
//	这个函数用来往数组里添加元素,如果stArray这个指针变量为NULL的话
//	表示没有这个数组,这个时候返回false,即无法往指定的数组里填东西
//	如果stArray不是null的话,就可以往进填,返回true
}

int WVector::Get(int index)
{
    if(index >= Count)//这里加入一个数组越界检查
        return -1;//如果输入的索引值大于数组中元素的总数,返回-1
    return stArray[index];
//	getter的作用也自不必说
}


void WVector::Update(int index, int item)
{
    if(index < Count)
        stArray[index] = item;
//	这里要多加一句,如果index,即这个索引值比总数小的话,才可以往进填东西
//	如果大的话,数组越界访问是不可以的!所以这里加一步判断,
//	如果越界的话不做处理就可以了。
}


bool WVector::Contain(int item)
{
    for (int j = 0; j < Count; j++)
    {
        if (stArray[j] == item)
        {
            return true;
        }
    }
    return false;
//检查数组中是否含有某一个元素,逻辑简单,不必多说。
}

最后,写主程序

上面的所有铺垫已经具备了,下面就是要在主程序中使用刚刚定义好的类,以及在主程序中使用类的成员函数来达到自己的目的。
代码如下(依然使用注释解释):

#include "WVector.h"

如果是多文件程序的话这句话必须要有!不然之前写半天就是白费力气…

下面是正常的主函数的代码(为了方便观察,具体操作与昨天的具体代码稍有不同,在此不就题论题,仅谈方法):

int  d;
    WVector v1;//声明一个刚定义好的WVector的对象v1

    cin >> d;

    v1.SetSize(d);

    int tmp = 0;//存放一个输入的待检查的数据
    //如果是严格按照昨天的程序的话,下面的for循环中记录数据即可
    
    for (int i = 0; i < d; i++)
    {
        cin >> tmp;//输入一个tmp,其实只要是对tmp赋值的操作都可以
        if (v1.Contain(tmp) == false)//检查v1中是否包含
            v1.Add(tmp);//不包含的话,加入
    }

    for (int i = 0; i < v1.Count; i++)//v1.Count就是v1中元素的个数
        cout << v1.Get(i)<< " ";//输出v1中的每一个元素

这就是所有的代码!

出现的一些问题

这个代码中依然有问题,
具体可以看int WVector::Get(int index){……}这个函数部分

int WVector::Get(int index)
{
    if(index >= Count)
        return -1;
    return stArray[index];
}
  • 这里,如果输入的索引越界,返回-1.
  • 但是,如果输入的某个索引,其对应的元素恰好也为-1呢?
  • 也就是说,即使这里出现越界,返回了-1,用户一下子直观上无从知晓到底是这个地方的元素就是-1,还是因为越界,返回了代表出现越界的-1。
  • 这里最好的一个方法就是,如果出现越界,能直接出现一个越界的提示,最好了。
  • 之后再想想这个怎么改……

写在最后

这是第二次更博了,没想到用一个题目能做出这么多东西,哈哈!
明天也要继续加油鸭,也要继续更博,总结总结!让自己沉淀的更多!
加油!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值