日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

理解C++之類模板

來源: 責編: 時間:2023-12-18 17:37:02 227觀看
導讀在前面我們介紹了《C++之函數模板》今天我們繼續來介紹模板的另外一種形式:類模板。與模板函數相似,類也可以被一種或多種類型參數化,標準庫中的容器類就是一個具有這種特性的典型例子。類模板的聲明我們通過一段例子代

在前面我們介紹了《C++之函數模板》Kgh28資訊網——每日最新資訊28at.com

今天我們繼續來介紹模板的另外一種形式:類模板。Kgh28資訊網——每日最新資訊28at.com

與模板函數相似,類也可以被一種或多種類型參數化,標準庫中的容器類就是一個具有這種特性的典型例子。Kgh28資訊網——每日最新資訊28at.com

Kgh28資訊網——每日最新資訊28at.com

類模板的聲明

我們通過一段例子代碼了解一下類模板的聲明:Kgh28資訊網——每日最新資訊28at.com

// 類模板聲明template <typename T>class MyClass{public:    T getT();    void setT(T t);private:    T t;};// 類成員函數實現template<typename T>T MyClass<T>::getT() {    return t;}template<typename T>void MyClass<T>::setT(T t) {    this->t = t;}int main(int argc, char* argv[]) {    // 類模板使用    MyClass<int> myClass;    myClass.setT(10);    std::cout << "myClass:" << myClass.getT() << std::endl;    return 0;}

首先也是使用關鍵字template和關鍵字typename對類模板進行聲明,當我們將一個類聲明為類模板之后,模板參數T可以像其他任何類型一樣,用于聲明成員變量和成員函數。Kgh28資訊網——每日最新資訊28at.com

類模板的成員函數

通過上面的實例代碼,我們看到在類模板的聲明內部函數時如果用到模板參數T,則不用再次使用template<typename T>,但是當實現類模板的內部函數時,如果用到了模板參數T,則還需要在函數的上方 使用template<typename T>進行標記。Kgh28資訊網——每日最新資訊28at.com

也即是說為了定義類模板的成員函數,你必須指定該成員函數是一個函數模板,而且你還需要使用這個類模板的完整類型限定符。Kgh28資訊網——每日最新資訊28at.com

或許你覺得每次定義類模板的內部函數都要使用到模板聲明,當內部函數較多時,則會產生非常多的不必要的聲明,此時我們可以直接在類的內部聲明加定義同時實現:Kgh28資訊網——每日最新資訊28at.com

// 類模板聲明template <typename T>class MyClass{public:    // 聲明加定義    T getT(){        return t;    }    // 聲明加定義    void setT(T t){        this->t = t;    }private:    T t;};

在類模板中只有那些被調用的成員函數,才會產生這些函數的實例化代碼。對于類模板,成員函數只有在被使用的時候才會被實例化。 顯然,這樣可以節省空間和時間;另一個好處是:對于那些“未能提供所有成員函數中所有操作的”類型,你也可以使用該類型來實例化類模板, 只要對那些“未能提供某些操作的”成員函數,模板內部不使用即可。Kgh28資訊網——每日最新資訊28at.com

類模板的特例化

同模板函數的特化一樣,你可以用模板實參來特化類模板,和函數模板的重載類似,通過特化類模板,我們可以優化基于某種特定類型的實現。Kgh28資訊網——每日最新資訊28at.com

在類模板的特化過程中有兩個步驟:Kgh28資訊網——每日最新資訊28at.com

  • 在類的起始處聲明一個template<>,接下來聲明用來特化類模板的類型。這個類型被用作模板實參,且必須在類名的后面直接指定。
  • 進行類模板的特化時,每個成員函數都必須重新定義為普通函數,原來模板函數中的每個T也相應地被進行特化的類型取代。

下面是一個模板類特化的例子:Kgh28資訊網——每日最新資訊28at.com

// 類模板聲明template <typename T>class MyClass{public:    // 聲明加定義    T getT(){        return t;    }    // 聲明加定義    void setT(T t){        this->t = t;    }private:    T t;};// 類模板聲明template <>class MyClass<std::string>{public:    // 聲明加定義    std::string getT(){        return t;    }    // 聲明加定義    void setT(std::string t){        std::cout << "調用特化類模板 setT" << std::endl;        this->t = t;    }private:    std::string t;};int main(int argc, char* argv[]) {    // 類模板使用    MyClass<std::string> myClass;    myClass.setT("hello word");    std::cout << "myClass:" << myClass.getT() << std::endl;    return 0;}

模板源碼組織模式

模板源碼的組織模式有好多種,這里只介紹兩種常用的:分別是包含模式和關鍵字export的分離模式。Kgh28資訊網——每日最新資訊28at.com

包含模式可以說是最常用也是最推薦的一種模式。這種模式就是將模板類的聲明和定義都放在同一個文件中,這個文件一般是擴展名為.hpp的文件。Kgh28資訊網——每日最新資訊28at.com

下面是一個類模板聲明定義和使用分開在不同文件的例子:Kgh28資訊網——每日最新資訊28at.com

MyClass.hpp#include <iostream>#include <memory>// 類模板聲明template <typename T>class MyClass{public:    // 聲明    T getT();    void setT(T t);private:    T t;};template<typename T>T MyClass<T>::getT() {    return t;}template<typename T>void MyClass<T>::setT(T t) {    this->t = t;}

在main函數中使用模板main.cpp:Kgh28資訊網——每日最新資訊28at.com

main.cpp#include <iostream>#include <memory>#include "MyClass.hpp"int main(int argc, char* argv[]) {    // 類模板使用    MyClass<std::string> myClass;    myClass.setT("hello word");    std::cout << "myClass:" << myClass.getT() << std::endl;    return 0;}

很明顯,包含模式因為包含了類模板的定義實現,因而明顯增加了包含頭文件.hpp的開銷,這會導致大大增加了編譯復雜程序所耗費的時間。 然而隨著現代的機器性能提升,這里帶來的編譯開銷基本可以忽略不計,因此這種模式成為了使用最多的模式。Kgh28資訊網——每日最新資訊28at.com

下面我們再來看看關鍵字export的分離模式。Kgh28資訊網——每日最新資訊28at.com

關鍵字export的功能使用是非常簡單的:在一個文件里面定義模板,并在模板的定義和(非定義的)聲明的前面加上關鍵字export。Kgh28資訊網——每日最新資訊28at.com

還是以上面的代碼為例:Kgh28資訊網——每日最新資訊28at.com

(1) MyClass.hKgh28資訊網——每日最新資訊28at.com

#include <iostream>#include <memory>// 類模板聲明export template <typename T>class MyClass{public:    // 聲明    T getT();    void setT(T t);private:    T t;};

(2) MyClass.cppKgh28資訊網——每日最新資訊28at.com

#include "MyClass.h"export template<typename T>T MyClass<T>::getT() {    return t;}export template<typename T>void MyClass<T>::setT(T t) {    this->t = t;}

以上代碼能否編譯通過取決于你的編譯器,大部分是無法編譯通過的,這代碼和包含模式對比起來是不是有一種脫褲子放屁的感覺?Kgh28資訊網——每日最新資訊28at.com

看起來關鍵字export的分離模式更加符合C++源碼組織習慣,為什么這種寫法再C++的模板沒有流行起來呢? 這是因為在C++標準推出幾年之后,也就只有極少的公司真正提供了對export關鍵字的支持。于是,export這個特性未能像其他C++特性那樣廣為流傳, 這就使得程序員在很多編譯器下都不能正常使用export的分離模式。Kgh28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-48742-0.html理解C++之類模板

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Python 的 match 有點好用,推薦試試

下一篇: Pandas的魅力:從數據處理到機器學習

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 岱山县| 巩义市| 莎车县| 赤壁市| 云南省| 历史| 刚察县| 高安市| 德安县| 文安县| 福海县| 炎陵县| 鄂伦春自治旗| 潞城市| 水富县| 濮阳县| 静乐县| 泰来县| 岳西县| 兴仁县| 丰原市| 五莲县| 蒙阴县| 绥宁县| 青田县| 收藏| 宜城市| 胶南市| 墨玉县| 信阳市| 莲花县| 天等县| 九江县| 广丰县| 兴业县| 黔西| 壶关县| 肃南| 宝兴县| 龙山县| 广东省|