模板類里面如何添加靜態(tài)變量

如果趕時間,直接看最后一部分怜森。

還是老規(guī)矩:為了避免歧義我還是要先列下我的環(huán)境

$ uname -a
Linux debian9-64-Desktop 4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u6 (2018-10-08) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516

需求:

寫個模板類仍律,有個自增唯一ID

這里只是給了一個思路,也是我在工作過程中使用到的低零。

需要建立一個 ReqSession.h

"C++模板類的成員函數(shù)定義與聲明必須在一個頭文件中"

#ifndef REQSESSION_H
#define REQSESSION_H
#include <stdint.h>
#include <iostream>
//自增的參數(shù)
static uint32_t m_sessionId =0 ;

//模板類
template <typename T>
class ReqSessionTMP
{
public:
    ReqSessionTMP(T* data){
        ++m_sessionId;
        m_data =data;
    }
    void printSession(){
        std::cout<<"模板類:id:"<<m_sessionId<<",param:"<<m_data<<std::endl;
        delete m_data; // 這里做了釋放的操作
    }
private:
    //攜帶的參數(shù)
    T * m_data =nullptr;
};

#endif // REQSESSION_H

如果發(fā)現(xiàn)修改模板類的頭文件沒有用處婆翔,則需要增加預(yù)編譯參數(shù) **-MMD**

在我的工程項(xiàng)目里面就是加到 *.pro 文件, QMAKE_CXXFLAGS += -MMD

開始調(diào)用:

void UA4Qml2::createReqSession(const QString str)
{
    //創(chuàng)建一個會話
    //基本數(shù)據(jù)類型
    //const char* conver to char* 掏婶,const char*  強(qiáng)轉(zhuǎn)char*
    std::string tmpStr = str.toStdString();
    char* c_str=new char[tmpStr.length()]; //注意這里的內(nèi)存釋放
    memcpy(c_str,tmpStr.c_str(),tmpStr.length());

    ReqSessionTMP<char> session(c_str) ;
    session.printSession();
}

看下打印

模板類:id:1,param:hello session
模板類:id:2,param:hello session

看到這里也許有人問啃奴,這里為啥要用模板類,用個void* 不就可以了嗎雄妥?

我們再繼續(xù)實(shí)踐最蕾,增加普通類,和上面的 ReqSessionTMP 放在同一個文件里( PS :c++就是不一樣依溯,一個文件可以放多個不同類的聲明,想我java好像不行

//普通類
class ReqSession
{
public:
    ReqSession(void* data){
        ++m_sessionId;
        m_data =data;
    }

    void printSession(){
        std::cout<<"普通類:id:"<<m_sessionId<<",param:"<<m_data<<std::endl;
        delete m_data;// 這里做了釋放的操作瘟则,注意這里沒有強(qiáng)轉(zhuǎn)
    }

private:
    //攜帶的參數(shù)
    void * m_data =nullptr;
};

事實(shí)證明黎炉,使用剛才的方式進(jìn)行打印,其實(shí)是沒有區(qū)別的醋拧。

我們現(xiàn)在改成復(fù)雜一點(diǎn)的例子慷嗜。我們再新建一個普通類,用于會話傳輸?shù)膬?nèi)容

#include <stdint.h>
#include <iostream>

class Session{
public:
    char * name =nullptr;
    uint32_t age =0;
    ~Session(){
        std::cout<<"~Session"<<std::endl;
    }
};

讓我們來看下兩種不同的調(diào)用

void UA4Qml2::createReqSession(const QString str)
{
    //復(fù)雜數(shù)據(jù)類型
    std::string tmpStr = str.toStdString();
    char* c_str=new char[tmpStr.length()];
    memcpy(c_str,tmpStr.c_str(),tmpStr.length());

    Session* session =new Session();
    session->name = c_str;
    #if 0
        ReqSession reqSession(session) ;
        //可以看到丹壕,沒有調(diào)用析構(gòu)函數(shù)
        reqSession.printSession();
    #else
        ReqSessionTMP<Session> reqSession(session) ;
        //可以看到調(diào)用了析構(gòu)函數(shù)
        reqSession.printSession();
    #endif
}

看下輸出的結(jié)果:

# 使用模板類
模板類:id:1,param:0x556faa8f7f20
~Session
模板類:id:2,param:0x556faa3c62a0
~Session

# 使用普通類
普通類:id:1,param:0x563bfec51f50
普通類:id:2,param:0x563bfe7055d0

好像有點(diǎn)偏題啊庆械。而且 本著哪里申請哪里釋放的原則,這里不應(yīng)該在模板類里面進(jìn)行 釋放內(nèi)存的操作菌赖,這是有問題的干奢。所以,如果把delete的相關(guān)代碼刪除盏袄,則兩邊效果是一致的忿峻,當(dāng)然,需要在外部進(jìn)行釋放內(nèi)存咯辕羽。

來逛尚,在說:上面這樣寫的就沒有問題嗎?

這是一個隱藏的很深的bug刁愿〈履【這是我今天特別想說的點(diǎn)】

如果有很多個不同的模板類,被打到了不同的庫里面會怎樣铣口?(什么意思滤钱?就是說我有很多個不同的特例模板類,然后打成不同的庫脑题,這個時候就有問題了)

當(dāng)然是件缸,static 關(guān)鍵字不生效了。啥叫不生效了叔遂,就是在同一個so里面的 static 還是唯一的他炊,但是和別的庫就會是一樣的Id,導(dǎo)致程序出現(xiàn)異常已艰。

來給出最終的方案痊末,因?yàn)榘裺tatic關(guān)鍵字放在了頭文件的緣故,所以導(dǎo)致上面的問題×ú簦現(xiàn)在改下凿叠,直接上代碼

采用繼承的方案

新建一個 basereqsession.h basereqsession.cpp

#include <stdint.h>
class BaseReqSession
{
public:
    BaseReqSession();
    static uint32_t& get_session_id();
};
#include "basereqsession.h"

BaseReqSession::BaseReqSession()
{}

static uint32_t m_session_id = 0; //在cpp里面進(jìn)行定義
uint32_t &BaseReqSession::get_session_id() //返回值類型必須是引用
{
 return m_session_id;
}

然后模板類只要繼承即可

#include "basereqsession.h"

template <typename T>
class ReqSessionTMP :BaseReqSession //這里用繼承
{
public:
    ReqSessionTMP(T* data){
        ++get_session_id();
        m_data =data;
    }

private:
    //攜帶的參數(shù)
    T * m_data =nullptr;
};

最后完善一下:之前的代碼

#ifndef REQSESSION_H
#define REQSESSION_H
#include <stdint.h>
#include <iostream>
#include "basereqsession.h"

template <typename T>
class ReqSessionTMP :BaseReqSession
{
public:
    ReqSessionTMP(T* data){
        autoIncreateSessionId();
        m_data =data;
    }

    int getSessionId()
    {
        return get_session_id();
    }
private:
    void autoIncreateSessionId()
    {
        ++get_session_id();
        if(get_session_id() == 0)
        {
            get_session_id() = 1;
        }
    }

private:
    //攜帶的參數(shù)
    T * m_data =nullptr;
};
#endif // REQSESSION_H
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子盒件,更是在濱河造成了極大的恐慌蹬碧,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件履恩,死亡現(xiàn)場離奇詭異锰茉,居然都是意外死亡呢蔫,警方通過查閱死者的電腦和手機(jī)切心,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來片吊,“玉大人绽昏,你說我怎么就攤上這事∏渭梗” “怎么了全谤?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長爷贫。 經(jīng)常有香客問我认然,道長,這世上最難降的妖魔是什么漫萄? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任卷员,我火速辦了婚禮,結(jié)果婚禮上腾务,老公的妹妹穿的比我還像新娘毕骡。我一直安慰自己,他們只是感情好岩瘦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布未巫。 她就那樣靜靜地躺著,像睡著了一般启昧。 火紅的嫁衣襯著肌膚如雪叙凡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天密末,我揣著相機(jī)與錄音狭姨,去河邊找鬼。 笑死苏遥,一個胖子當(dāng)著我的面吹牛饼拍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播田炭,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼师抄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了教硫?” 一聲冷哼從身側(cè)響起叨吮,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤辆布,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后茶鉴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锋玲,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年涵叮,在試婚紗的時候發(fā)現(xiàn)自己被綠了惭蹂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡割粮,死狀恐怖盾碗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舀瓢,我是刑警寧澤廷雅,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站京髓,受9級特大地震影響航缀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜堰怨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一芥玉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诚些,春花似錦飞傀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绞吁,卻和暖如春幢痘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背家破。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工颜说, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人汰聋。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓门粪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親烹困。 傳聞我的和親對象是個殘疾皇子玄妈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容