類模板的分離編譯-創(chuàng)新互聯(lián)

一直覺得模板類是特別神奇的東西,它可以構(gòu)造出不同類型的對象,使代碼更加的靈活。這個(gè)過程就是類模板的實(shí)例化。

成都創(chuàng)新互聯(lián)成立以來不斷整合自身及行業(yè)資源、不斷突破觀念以使企業(yè)策略得到完善和成熟,建立了一套“以技術(shù)為基點(diǎn),以客戶需求中心、市場為導(dǎo)向”的快速反應(yīng)體系。對公司的主營項(xiàng)目,如中高端企業(yè)網(wǎng)站企劃 / 設(shè)計(jì)、行業(yè) / 企業(yè)門戶設(shè)計(jì)推廣、行業(yè)門戶平臺運(yùn)營、成都App定制開發(fā)手機(jī)網(wǎng)站制作設(shè)計(jì)、微信網(wǎng)站制作、軟件開發(fā)、服務(wù)器托管等實(shí)行標(biāo)準(zhǔn)化操作,讓客戶可以直觀的預(yù)知到從成都創(chuàng)新互聯(lián)可以獲得的服務(wù)效果。

 我們使用類的模板寫一個(gè)stack類:

#include<assert.h>
#include"Seqlist1.h"
using namespace std;
template<class T,template<class> class Container  = Seqlist>
class Stack
{
public:
	void Push(const T& x)
	{
		_con.Pushback(x);
	}
	void Pop()
	{
		_con.Popback();
	}
	bool Empty()
	{
		return Size() == 0;
	}
	size_t Size()
	{
		return _con.Size();
	}
	T& Top()
	{
		size_t size = Size();
		assert(size > 0);
		return _con[size - 1];
	}
	void print()
	{
		_con.Print();
	}
	T& operator[](size_t index)
	{
		return _con[index];
	}
protected:
	Container _con;
};

 其中我們可以傳入不同類型的T,class Continer是類型T的一個(gè)容器,這里默認(rèn)是用自定義的一個(gè)順序表來當(dāng)容器。編譯器就會構(gòu)造出不同的代碼出來。

 這樣的實(shí)現(xiàn)方式是在類內(nèi)定義成員函數(shù),并把整個(gè)類放在.h中,這種方式叫做類模板的包含模式。這樣的定義方式是有好處的,要使用Stack這個(gè)類,只要在頭文件內(nèi)包含類體就可以了,編譯器很容易就可以找到類的定義。當(dāng)然這種方式是有弊端的,如果一個(gè)類的成員函數(shù)個(gè)數(shù)很多并且很復(fù)雜,無疑在你去閱讀或者修改定義的時(shí)候會讓人很頭疼,不能快速找到成員函數(shù)的定義。

 還好C++提供了另外一種方式——將成員函數(shù)的聲明放在類體內(nèi).h中,將函數(shù)的定義放在.cpp中,就相當(dāng)與類外定義,我們把這種方式叫做類模板的分離模式。這樣寫出來的代碼是很美觀的,并且易于修改。

//.h文件
#include<assert.h>
#include"Seqlist1.h"
using namespace std;
template<class T,template<class> class Container  = Seqlist>
class Stack
{
public:
	void Push(const T& x);
	void Pop();
	bool Empty();
	size_t Size();
	T& Top();
	void print();
	T& operator[](size_t index);
protected:
	Container _con;
};

//.cpp文件
//類外定義

template<class T,template<class> class Container  = Seqlist>
void Push(const T& x)
{
_con.Pushback(x);
}


template<class T,template<class> class Container  = Seqlist>
void Pop()
{
_con.Popback();
}

template<class T,template<class> class Container  = Seqlist>
bool Empty()
{
return Size() == 0;
}

template<class T,template<class> class Container  = Seqlist>
size_t Size()
{
return _con.Size();
}

template<class T,template<class> class Container  = Seqlist>
T& Top()
{
size_t size = Size();
assert(size > 0);
return _con[size - 1];
}

template<class T,template<class> class Container  = Seqlist>
void print()
{
_con.Print();
}

template<class T,template<class> class Container  = Seqlist>
T& operator[](size_t index)
{
return _con[index];
}

 類模板的分離模式就會牽扯出一些問題,比如說編譯器在構(gòu)造對象的時(shí)候它怎么找函數(shù)的定義的,因?yàn)楹瘮?shù)的定義是在.cpp文件中的。這就是類模板的分離編譯問題。

 假設(shè)我們stack類是放在stack.h中的,成員函數(shù)的定義放在stack.cpp中的,然后類的調(diào)用放在main.cpp中,并且在main.cpp中包含了stack.h。

 按照我們通常的思路:

  • 編譯main.cpp時(shí),編譯器不知道f(f是成員函數(shù)中的任意一個(gè)函數(shù))的實(shí)現(xiàn),所以當(dāng)碰到對它的調(diào)用時(shí)只是給出一個(gè)指示,指示連接器應(yīng)該為它尋找f的實(shí)現(xiàn)體。這也就是說main.obj中沒有關(guān)于f的任何一行二進(jìn)制代碼。

  • 編譯test.cpp時(shí),編譯器找到了f的實(shí)現(xiàn)。于是乎f的實(shí)現(xiàn)(二進(jìn)制代碼)出現(xiàn)在test.obj里。

  • 連接時(shí),連接器在test.obj中找到f的實(shí)現(xiàn)代碼(二進(jìn)制)的地址(通過符號導(dǎo)出表)。然后將main.obj中懸而未決的call XXX地址改成f實(shí)際的地址,pofect。

但是當(dāng)你編譯的時(shí)候,編譯器就會報(bào)鏈接錯(cuò)誤,找不到成員函數(shù)的定義。說明我們的思路是錯(cuò)誤的。對于模板,在沒有實(shí)例化出對象之前是不會被編譯成二進(jìn)制代碼的,而實(shí)例化是在程序運(yùn)行的時(shí)候(也就是用到模板的時(shí)候)才實(shí)例化出對象,實(shí)例化是在編譯器對代碼進(jìn)行編譯的后面才發(fā)生的。這樣問題就迎刃而解了,我們得手動(dòng)的在main中包含.cpp文件,讓編譯器知道有函數(shù)的定義,這樣編譯器就不會報(bào)錯(cuò)了。

這里有必要提醒(總結(jié))一下的是

  • 如果你的類不是用模板實(shí)現(xiàn)的,就不會有分離編譯的問題,也就是說,即使你的類的成員函數(shù)是在類外定義的也不用include .cpp文件,不管你用沒用到都會實(shí)例化出代碼出來,就會編譯成二進(jìn)制文件,在鏈接時(shí)就會鏈接起來。

  • 如果你的類是模板類,并且想要在類外定義成員函數(shù),就必須include .cpp文件。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

分享文章:類模板的分離編譯-創(chuàng)新互聯(lián)
標(biāo)題路徑:http://www.muchs.cn/article20/dpgsjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序定制網(wǎng)站、關(guān)鍵詞優(yōu)化網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)