D21.1.0 C++,从未开启你的大门

这不是一篇纯技术文章,文末有煽情。

先解决技术问题。

在项目中我开发后端采集程序。项目开始,我使用的红外相机类型是CX320,后来因为某些原因不得不换同一个牌子的其他类型相机CG640。这两款相机使用的SDK是一样的,但是两款相机使用的具体函数不一样。

这两个相机有两点不一样:

  • 采集的图片大小不一样,一个是320*240,一个是640*480;

  • 采集红外数据的具体函数不一样,更直观的表达是相机型号不一样,一个是A型号,另一个是B型号。

而实际中,A型号中有320*240和640*480两种,B型号中也有这两种。细分相当于有四种相机,现在要求用一个版本就能解决四个不同相机采集的问题。那如何解决传入某一种型号的相机,程序就能自动判断调用属于该类型相机的函数呢?

解决方法:使用类的派生特性可以解决这个问题。根据传入不同的相机类型,派生相对应的对象,通过对象调用对应相机的函数。

我将这个问题分成两个部分。

01 如何做到调用属于特定相机的特定函数?

基类CoxInfraCam定义如下:

class  CoxInfraCam
{

public:
    CoxInfraCam();
    explicit CoxInfraCam(const int _width, const int _height);
    virtual ~CoxInfraCam();
public:
    virtual bool InitialCamera();
    virtual bool ConnectCamera();
    virtual bool DisconnectCamera();
    virtual bool StartCapture();
    virtual bool StopCapture();

    virtual bool DiffrentFun1();

    virtual bool DiffrentFun2();

    virtual bool DiffrentFun3();
}

注:DiffrentFun的命名只是为了区分,并不是实际程序中的命名。*

最下面的三个函数DiffrentFun1、DiffrentFun2和DiffrentFun3,不同的相机实现方法不一样。所以把这个三个函数设置为虚函数,这样就可以在派生类中更改这三个函数。基于类CoxInfraCam派生了两个类CXInfraCam和CGInfraCam,声明和实现如下:

CXInfraCam类声明

class CXInfraCam :
    public CoxInfraCam
{
public:
    CXInfraCam();
    explicit CXInfraCam(const int _width, const int _height);
    ~CXInfraCam();

    virtual bool DiffrentFun1();

    virtual bool DiffrentFun2();

    virtual bool DiffrentFun3();
private:
    int m_iWidth_;
    int m_iHeight_;
};

CXInfraCam类实现

CXInfraCam::CXInfraCam(const int _width, const int _height) :CoxInfraCam(_width, _height)
{
    m_iWidth_ = _width;
    m_iHeight_ = _height;
}

 bool CXInfraCam::DiffrentFun1() {……}

 bool CXInfraCam::DiffrentFun2() {……}

 bool CXInfraCam::DiffrentFun3() {……}

CGInfraCam类声明

class CGInfraCam :
    public CoxInfraCam
{
public:
    CGInfraCam();
    explicit CGInfraCam(const int _width, const int _height);
    ~CGInfraCam();

    virtual bool DiffrentFun1();

    virtual bool DiffrentFun2();

    virtual bool DiffrentFun3();

private:
    int m_iWidth_;
    int m_iHeight_;
};

CGInfraCam类实现

CGInfraCam::CGInfraCam(const int _width, const int _height) : CoxInfraCam(_width, _height)
{
    m_iWidth_ = _width;
    m_iHeight_ = _height;
}

 bool CGInfraCam::DiffrentFun1() {……}

 bool CGInfraCam::DiffrentFun2() {……}

 bool CGInfraCam::DiffrentFun3() {……}

从上面两个类的定义可以看到只需要修改DiffrentFun*就可以,其他的函数都从基类CoxInfraCam中继承。

例如现在new了类CXInfraCam的对象。

CoxInfraCam* pThis = new CXInfraCam(width, height); 
//指向派生类的基类指针,可以调用派生类中修改过的虚函数

在new新对象的过程中,调用构造函数CXInfraCam(const int _width, const int _height),同时还调用父类的构造函数CoxInfraCam(_width, _height)。这一做法就能解决调用属于特定相机的特定函数。

02 如何根据传入相机类型生成该类型的对象。

我先定义了一个枚举类型作为传入的参数。

typedef enum{
    TYPE_CX320 = 0,
    TYPE_CX640 = 1,
    TYPE_CG320 = 2,
    TYPE_CG640
}COXCAMTYPE;

这个类型表示了有四种不同类型的相机。

然后根据传入的不同参数,new不同的相机对象,看代码更加直观一些。

void* _stdcall CIn_IRCam_CreateObject(COXCAMTYPE _coxType)
{
     int width;
     int height;
    CoxInfraCam* pThis = NULL;
    switch (_coxType)
    {
    case TYPE_CX320:
        width = 320;
        height = 240;
        pThis = new CXInfraCam(width, height);
        break;
    case TYPE_CX640:
        width = 640;
        height = 480;
        pThis = new CXInfraCam(width, height);
        break;

    case TYPE_CG320:
        width = 320;
        height = 240;
        pThis = new CGInfraCam(width, height);
        break;
    case TYPE_CG640:
        width = 640;
        height = 480;
        pThis = new CGInfraCam(width, height);
        break;
    default:
        pThis = NULL;
        break;
    }
    return pThis;
}

上面的内容只写出了解决这个问题的关键部分。

在项目的末尾,突然说要换相机确实是让人抓狂的。有经验的人能够马上想出比这更好的解决方案,可能它只需要花上10分钟时间就能想透想明白。而我遇到这个问题的时候,我一共改了三版代码,累计时间至少三小时。

1.马上更改CX320所在工程的函数,重新调试。

已经没办法冷静思考了,时间不多,并且两个相机不同的函数并不多,花不了多长时间就能改出来。所以马上在修改原有工程的代码。

2.更改CoxInfraCam类的实现,传入camera type参数,增加一个switch的语法,根据这个参数选择CX320或者CG640。

既然两个相机大部分实现代码都是一样的,那我就传入不同相机类型,根据类型去调用相应的函数,马上想到switch语句。

3.把CoxInfraCam当作一个基类,分别派生出属于CX320的CXInfraCam和属于CG640的CGInfraCam。在对应的类里面增加相应的函数。

该处上一版代码之后,这个项目也没那么赶了,有足够的时间去思考。确实我发现好像还有更灵活不像上面两种那么机械的方法。

真正的知识确实是在具体项目中获取到的。研究生期间读《C++ primer Plus 第五版》的时候,内心极度痛苦,读这样的技术书籍真的很枯燥,字全都认识可就是不明白作者说的是什么。每天即便花上四五小时去读这本书,找工作的时候可能还是什么都不懂。那段时间,一直不能静下心来认真看这本书,也不知道自己到底怎么了,怎么就静不下心来。

没有项目依托去学C++真的是浪费生命,即便花了很长时间去学,你了解地可能也不会深入。那怎么办?很多人想做软件开发,却发现自己的导师是镀膜的,怎么办?你要做的是先去了解用C++可以做什么样的开发,然后再去网上找项目,看别人的代码,再模仿别人的代码。模仿是提升代码能力的最最有效的途径,这确实是我个人最深切的体会。

2016年10月去臻识面试的时候,公司总经理问我有没写过一个类,我说写过,这个类是把所有的关于计算的函数放在一起。总经理只是笑了笑,最后给我的回复是:我不会跟你签正式的三方协议,可以考虑让你实习一段时间,看你表现再签。很显然,我根本不知道什么是类,什么是C++。虽然读研期间,每天都在写都在用,但是从来未想过为什么是这样写,还有没其他写法?

后来在臻识实习的三个月里,我的自信被打击了,我也开始认为我自己能力不行,我也认为自己做不了软件开发。接下来就是转岗,再接下来就是我人生中黑暗的十个月(这句话也只是基于我个人价值观进行评判,于公司及岗位无关):转到技术支持,全国到处跑。一度怀疑人生,找不到人生的意义。

终究我还是变成了更好的我,谢谢臻识,愿好!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值