最近用的C++模板

来源:互联网 发布:幸运28软件下载 编辑:程序博客网 时间:2024/06/12 01:39

最近写代码,发现很多代码都重复的出现,只是有细微的差别,之前用一个基类来做,但是发现有些地方需要根据类型来实例化。最后我想想就改用模板来实现了,之前对C++的模板只是有耳闻,但在实际项目中确很少去用。我把使用模板的时候需要的问题记录下来。

在项目中我总是遇到要写一些单例的东西,比如读取一些经常要用到的配置信息,我需要把他存在内存里面。这个时候我通常写一个单例,但是每次我都得写同样的代码,之前我就这么算了,每次写一遍,现在想想这样做重复的工作好吗,经过这次,我把它写成一个模板,因为有好几个地方需要用到。

我的单例模板:

#ifndef TEMPLATESINGLETON#define TEMPLATESINGLETON/**单例模板 * @author zp * @date 2015-04-27 */template<typename T>class Singleton{public:    static T * getInstance()    {        static T instance;        return &instance;    }public:    Singleton(){}    ~Singleton(){}private:    Singleton(const Singleton<T> &);    Singleton& operator=(const Singleton<T> &);};#endif // TEMPLATESINGLETON

单例一般要把构造函数变成私有的,但是我把这个变成私有的时候,在继承的时候总是出现问题,改成公有就没有问题。

我在代码中是这样使用的

#include "TemplateSingleton.h"#include <QMap>#include <QString>class AppConfig:public Singleton<AppConfig>{public:    AppConfig();    ~AppConfig();public:    QString getValueByKey(const QString& key);private:    bool loadFromAppConfigFile();    bool loadFromFile(const QString& fileName);private:    QMap<QString,QString> mapValue;};#endif 

//调用就像其他单例一样调用
AppConfig::getInstance()->getValueByKey(“”);

具体实现就不说了,所有的都能够这么用,我感觉这让我写了好多代码,挺方便。

后来我在程序中另外一处也用了模板。。需求是这样的,我从一个webservice中获取数据,数据格式都是统一的。
我写了一个方法来获取webservice的数据,这个方法,之前在博客上写过。只是做了一些修改。这部分代码直接从我写的代码上拿过来,因为没有涉及到数据的定义,应该没什么问题。
不知道这个方式合不合适,但是现在用了,感觉还挺好

class BmilpManagerTemplate{public:    BmilpManagerTemplate();    virtual ~BmilpManagerTemplate();public:    /**     * @brief addBmilpObj 添加对象     * @param method  webservice方法     * @param obj   对象     * @return     */     static int addBmilpObj(const QString& method,const T & obj);    /**     * @brief updateBmilpObjById 通过Id更新数据     * @param method webservice方法     * @param newObj     * @return     */     static int updateBmilpObj(const QString & method,const T & newObj);     /** 根据id得到对象信息      * @brief getBmilObjById      * @param method 方法      * @param paramStr 一般是"id"      * @param id   id      * @param newObj 对象      * @return      */     static QString getBmilObjById(const QString& method, QString paramStr, int id, T & newObj);     /**      * @brief getAllBmilpObjList 获取所有数据,不分页      * @param method      * @param param      * @param selObjList      * @return      */     static QString getAllBmilpObjList(const QString & method,QMap<QString,QVariant> & param,QList<T*> & selObjList);    /**     * @brief getAllPageBmilpObjList 分页查询得到所有的数据     * @param method     * @param param     * @param selObjList     * @return     */     static QString getAllPageBmilpObjList(const QString & method,QMap<QString,QVariant> & param,QList<T*> & selObjList);    /**     * @brief selectBmilpObjListPage 分页查询     * @param method     * @param param     * @param selObjList     * @param pageCount     * @param pageNo     * @return     */     static QString getBmilpObjListPage(const QString & method,QMap<QString,QVariant> & param,QList<T*> & selObjList,int& pageCount,int & pageNo);private:    /**     * @brief addupdateBmilpObj 添加和修改对象方法     * @param method        webservice 方法     * @param obj           对象     * @param isUpdateFun   是否是更新方法     * @return     */     static int addupdateBmilpObj(const QString & method,const T & obj,bool isUpdateFun=false);};#include "BmilpManagerTemplate.cpp"

// BmilpManagerTemplate.cpp文件按

template<typename T>BmilpManagerTemplate<T>::BmilpManagerTemplate(){}template<typename T>BmilpManagerTemplate<T>::~BmilpManagerTemplate(){}template<typename T>int BmilpManagerTemplate<T>::addBmilpObj(const QString &method, const T &obj){    return addupdateBmilpObj(method,obj,false);}template<typename T>int BmilpManagerTemplate<T>::updateBmilpObj(const QString &method, const T &newObj){    return addupdateBmilpObj(method,newObj,true);}template<typename T>QString BmilpManagerTemplate<T>::getBmilObjById(const QString &method, QString paramStr, int id, T &newObj){    BmilpWebServiceData data;    QMap<QString,QVariant>  param;    param.insert(paramStr,id);    QNetworkReply::NetworkError netError = WebServiceHelp::getInstance()->sendGetRequest(method,param,data);    if(netError ==QNetworkReply::NoError)    {        if(data.getCode() == WebServiceReturnCode::webServiceSuccessCode)        {            QMap<QString,QVariant> dataMap = data.getData().toMap();            newObj.fromMap(dataMap);        }    }    qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<data.getMessage();    return data.getCode();}template<typename T>QString BmilpManagerTemplate<T>::getAllBmilpObjList(const QString & method,QMap<QString,QVariant> & param,QList<T*> & selObjList){    BmilpWebServiceData data;    QNetworkReply::NetworkError netError = WebServiceHelp::getInstance()->sendGetRequest(method,param,data);    if(netError ==QNetworkReply::NoError)    {        if(data.getCode() == WebServiceReturnCode::webServiceSuccessCode)        {            if(data.getData().type()==QVariant::List)            {                QList<QVariant> dataList = data.getData().toList();                foreach(QVariant var,dataList)                {                    T* pbType = new T();                    QMap<QString,QVariant> dataMap = var.toMap();                    pbType->fromMap(dataMap);                    selObjList.append(pbType);                }            }        }    }    qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<data.getMessage();   return data.getCode();}template<typename T>QString BmilpManagerTemplate<T>::getAllPageBmilpObjList(const QString &method, QMap<QString, QVariant> &param, QList<T *> &selObjList){     QString retCode = WebServiceReturnCode::webServiceFailCode;    int pageNo = 1;    int pageCount = 0;    do    {        retCode = getBmilpObjListPage(method,param,selObjList,pageCount,pageNo);        pageNo++;    }while(pageNo<=pageCount);    qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<data.getMessage();    return retCode;}template<typename T>QString BmilpManagerTemplate<T>::getBmilpObjListPage(const QString &method, QMap<QString, QVariant> &param, QList<T *> &selObjList, int &pageCount, int &pageNo){    QString retCode = WebServiceReturnCode::webServiceFailCode;    BmilpWebServiceData data;    QNetworkReply::NetworkError netError = WebServiceHelp::getInstance()->sendGetRequest(method,param,data);    if(netError ==QNetworkReply::NoError)    {        if(jsonData.getCode()==WebServiceReturnCode::webServiceSuccessCode)        {            QVariantMap dataMap = data.getData().toMap();            pageCount = dataMap.value("pageCount").toInt();            pageNo  = dataMap.value("pageNo").toInt();            retCode = data.getCode();            QVariant result = dataMap.value("result");            if(result.type() == QVariant::List)            {                QList<QVariant> resultList = result.toList();                foreach(QVariant var,resultList)                {                    QMap<QString,QVariant> posData = var.toMap();                    T * t = new T();                    t->fromMap(posData);                    selObjList.append(t);                }            }        }    }    qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<data.getMessage();    return retCode;}template<typename T>int BmilpManagerTemplate<T>::addupdateBmilpObj(const QString &method, const T &obj, bool isUpdateFun){    int id = -1;    QVariantMap param;    QMap<QString,QVariant> dataMap = obj.toMap(isUpdateFun);    QVariant var(dataMap);    QJsonDocument jsonDoc = QJsonDocument::fromVariant(var);    QByteArray ba = jsonDoc.toJson(QJsonDocument::Compact);    qDebug()<<QString::fromUtf8(ba);    BmilpWebServiceData jsonData;    QNetworkReply::NetworkError netError = WebServiceHelp::getInstance()->sendPostRequest(method,param,ba,jsonData);    if(netError==QNetworkReply::NoError)    {        if(jsonData.getCode()==WebServiceReturnCode::webServiceSuccessCode)        {            if(jsonData.getData().isValid())            {                bool OK = false;                id = jsonData.getData().toInt(&OK);                if(!OK)                {                    id = -1;                }            }        }    }    qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<jsonData.getMessage();    return id;}

看看调用的地方吧:
因为模板里面有调用t->fromMap(posData); 所以t必须实现fromMap这个方法来初始化。
我程序设计里面这个t一定是我定义的object基类继承下来的,而且在基类里我把fromMap定义成了纯虚方法。
Type表示类型,obj表示对象
BmilpManagerTemplate::addBmilpObj(method,obj);
这样做我就不用吧每次调用webservice添加,重新写一遍,只是这么调用一下就解决了。
起始添加这个函数并不能体现模板的好,因为这个方法我之前用基类的方式就可以实现。
但是查询的时候不行,因为查询的时候我不能动态的知道类型,通过模板我就可以根据不同的类型给定不同的参数。

编写模板遇到的问题。之前我直接在工程里面建立的一个类,然后把方法写好,分别写在了两个不同的文件上,声明写在了头文件上,定义写在了cpp文件上,这样程序编译的时候老是出现错误,说某某函数为未找到。后来我翻了一下书籍,找到了答案。
我采取解决的办法是在头文件最后加入#include “BmilpManagerTemplate.cpp”
然后把cpp文件从工程中移除,因为模板需要在编译的时候就知道定义,所以必须让编译器知道定义,加了这个文件,起始可以把实现写到另一个头文件中这样更好。在代码中加入
include “BmilpManagerTemplate.cpp”感觉挺别扭。加了这句话后如果没有从工程中去掉.cpp文件的话,也会报错的,因为编译器会编译cpp文件,但是这个时候它是一个模板,没有具体的类型,所以会报错。去掉后编译就通过了,因为对模板的概念什么的都不熟,所以犯了很多错,很多错报的也莫名其妙不好找,花了不少时间,在此记下来。

关于模板的问题,我想过段时间,我找本书系统的学习一下,把学习的笔记给记下来,现在只是用到哪记到哪。

很多时候我只是遇到了问题,然后去解决问题,并没有那么追根究底的去把一件事情弄得很透彻。以前怎么解决的也没有记录下来,所以遇到同样的问题。我又要做一遍原来要走的路,这样不知不觉在路上花了比别人多倍的时间。现在觉得应该把一些东西记下来,哪怕它再小。因为网络这东西谁说的准,今天本来可以查到的东西,明天就消失了。

0 0