五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網 會員登陸 & 注冊

2 引入模板,支持復雜類型

2023-03-06 15:05 作者:HC_0702  | 我要投稿

本項目GitHub: HuangCheng72/HCSTL: 我的STL實現(xiàn) (github.com): https://github.com/HuangCheng72/HCSTL

進入正文。

我們在上一篇已經實現(xiàn)了只支持double類型的vector,那么問題來了,如果我們要實現(xiàn)支持C++全部內建類型的vector,該怎么做?我們可以考慮全都重新實現(xiàn)一遍,但這樣工作量顯然是太大了。所以我們需要C++的模板機制,把vector變成一個模板類。內建類型,很好實現(xiàn),直接加上模板語句 template 開文本替換用 T (其實你自己可以指定任意名字,Tp,E什么的都行)全部替換一下double就行了:

但是問題來了,如果不是內建類型的數(shù)據(jù)呢?比如用戶自己定義的類的對象這種數(shù)據(jù),它和內建類型的數(shù)據(jù)有什么區(qū)別?

大家都上過C++課,也都應該知道,類的對象是new出來的,而內建類型的數(shù)據(jù)是可以不用new的(要是非要new那我也沒話說)。

而new一個類的對象,涉及了兩個操作:

  1. 申請一塊內存空間,用來存放這個對象。

  2. 在這塊空間上根據(jù)參數(shù)輸入調用類相應的構造函數(shù),創(chuàng)建這個對象(初始化內存空間的各個參數(shù))。

在我們上面的代碼中,我們可以看到,在vector的構造函數(shù)和輔助函數(shù)中,我們都已經申請了一段內存空間(數(shù)組)用來存放vector中的數(shù)據(jù)。我們可以有兩種存放對象的方法:

  1. 將vector的數(shù)組所存放數(shù)據(jù)的類型改為T類型的指針,然后每個元素都是一個對象的指針,對象直接new出來。

  2. 將對象在vector的數(shù)組空間上創(chuàng)建。

為了與其他類型相統(tǒng)一,我們采用第二種方法,第一種方法如果感興趣的話可以自行嘗試,本教程對此不討論。

針對第二種方法,C++有一種運算符,placement new(定位new),它的作用是在指定的內存空間上創(chuàng)建對象,用法如下:

我們可以考慮采用定位new,來實現(xiàn)我們的方法,將對象在vector的數(shù)組空間上創(chuàng)建。

以帶參構造函數(shù)為例:

那么就引出一個問題,我們該怎么判斷呢?

我們自然而然可以想到,能不能實現(xiàn)一個判斷的函數(shù),這個函數(shù)輸入的參數(shù)是一種類型,返回一個bool值,如果輸入的參數(shù)是C++內建類型,則返回true,如果輸入的參數(shù)不是C++內建類型,則返回false,這樣是不是能夠解決問題了?

但是很遺憾,C++的函數(shù)參數(shù)不能是一種類型。當然,如果你要將類型名字轉化為字符串,然后用字符串進行判斷也是可以的,不過本教程對此不討論。

STL 對此采取的方法是類型萃?。╰ype_traits),它的意義就是將類型的信息提取出來,可以通過一個判斷機制進行判斷,達到我們的目的。類型萃取的實現(xiàn)采用了模板特化的思路。

在這里需要介紹一下POD類型:

POD(Plain Old Data)類型,指的是C++的內建數(shù)據(jù)類型,還有原生指針和C風格的結構體聯(lián)合體等。標準的定義是:能用C的memcpy()等函數(shù)進行操作 的類、結構體或聯(lián)合體。POD類型有以下標準:

  1. 沒有用戶自定義的構造函數(shù)、析構函數(shù)、拷貝賦值運算符;

  2. 沒有虛函數(shù)和虛基類;

  3. 所有非靜態(tài)成員都是public;

  4. 所有非靜態(tài)成員都是POD類型;

  5. 沒有繼承或只繼承了POD類型。

POD類型和復雜數(shù)據(jù)類型最大的區(qū)別是四個方面:構造(默認構造器)、析構、賦值、復制(拷貝構造器),即default_constructor,destructor,assignment_operator,copy_constructor。 復雜數(shù)據(jù)類型先天缺少這四樣(編譯器給它加上的不算),而可以認為POD類型是先天具備或者 根本不用考慮 這四樣。

請新建一個頭文件為 type_traits.h ,在這個文件中實現(xiàn)類型萃取。

首先用兩個空結構體表示true和false的結果(不用bool類型的原因是因為空結構體不占用內存空間,bool變量還占用1字節(jié)空間):

然后利用C++的模板參數(shù)特化,將這兩個結構體轉化為bool值可以用于判斷。

這是類型萃取的模板類:

這是針對內建類型的特化實現(xiàn):

類型萃取這部分使用結構體模板實現(xiàn),最大的好處是空模板不占用內存空間(如果使用bool變量必然要占用至少一個字節(jié)的內存空間),同時結構體類型還可以作為模板參數(shù)傳遞,還有就是C風格結構體也是POD,這樣就不用管構造和析構的事情了。

所以,通過類型萃取,我們就可以寫我們的判斷條件了,還是以之前的帶參構造函數(shù)為例,可以寫成:

因此,我們可以實現(xiàn)支持POD和非POD(non-POD)類型數(shù)據(jù)的vector了。

修改main.cpp,嘗試運行一下non-POD類型的簡單測試:

但是我們會發(fā)現(xiàn)運行不了。我這里的IDE報錯為:

通過查詢,該錯誤代碼 0xC0000374 的含義為 A heap has been corrupted ,即堆內存損壞。

debug發(fā)現(xiàn),問題出在輔助函數(shù)這里。

這是怎么回事呢?

分析代碼上下文我們發(fā)現(xiàn)了一個問題。

這就出現(xiàn)了歧義,編譯器不知道你要銷毀的是到底是哪個,貿然銷毀導致堆內存損壞。這個問題在析構函數(shù)中也是一樣存在的。

但是我們暫時沒有好的解決方法,所以先擱置這個問題,加一個判斷,先run起來再說

run起來,可以看到main.cpp中我們的簡單測試順利過關。

歡迎訪問本項目的GitHub倉庫,如果對您有幫助,麻煩給項目一個star,謝謝!

HuangCheng72/HCSTL: 我的STL實現(xiàn) (github.com): https://github.com/HuangCheng72/HCSTL

2 引入模板,支持復雜類型的評論 (共 條)

分享到微博請遵守國家法律
定襄县| 尼木县| 扶余县| 离岛区| 临湘市| 太康县| 禹州市| 双辽市| 陆丰市| 兴国县| 巴林左旗| 平利县| 乡城县| 清镇市| 晴隆县| 九寨沟县| 罗定市| 泗水县| 奉贤区| 平陆县| 杨浦区| 吐鲁番市| 凤凰县| 桦南县| 湟源县| 蕲春县| 天镇县| 遵化市| 观塘区| 平遥县| 怀远县| 留坝县| 凤台县| 安阳市| 温泉县| 建始县| 玛多县| 公主岭市| 射洪县| 怀柔区| 兴安县|