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

當(dāng)前位置:首頁(yè) > 科技  > 軟件

玩轉(zhuǎn)C++方法模板,編程技能秒提升

來(lái)源: 責(zé)編: 時(shí)間:2023-12-15 17:17:44 298觀看
導(dǎo)讀方法模板C++ 中的方法模板C++ 允許對(duì)類的單個(gè)方法進(jìn)行模板化。這種方法被稱為方法模板,可以存在于普通類或類模板中。編寫方法模板實(shí)際上就是為許多不同類型編寫該方法的不同版本。方法模板對(duì)于類模板中的賦值運(yùn)算符和

方法模板

C++ 中的方法模板

C++ 允許對(duì)類的單個(gè)方法進(jìn)行模板化。這種方法被稱為方法模板,可以存在于普通類或類模板中。編寫方法模板實(shí)際上就是為許多不同類型編寫該方法的不同版本。方法模板對(duì)于類模板中的賦值運(yùn)算符和拷貝構(gòu)造函數(shù)非常有用。ZBX28資訊網(wǎng)——每日最新資訊28at.com

ZBX28資訊網(wǎng)——每日最新資訊28at.com

警告:虛方法和析構(gòu)函數(shù)不能是方法模板。ZBX28資訊網(wǎng)——每日最新資訊28at.com

考慮僅有一個(gè)模板參數(shù)的原始 Grid 模板:元素類型。您可以實(shí)例化許多不同類型的網(wǎng)格,例如 int 和 double:ZBX28資訊網(wǎng)——每日最新資訊28at.com

Grid<int> myIntGrid;Grid<double> myDoubleGrid;

然而,Grid<int> 和 Grid<double> 是兩種不同的類型。如果你編寫一個(gè)接受 Grid<double> 類型對(duì)象的函數(shù),你不能傳遞 Grid<int>。即使你知道 int 網(wǎng)格的元素可以復(fù)制到 double 網(wǎng)格的元素中,因?yàn)?nbsp;int 可以轉(zhuǎn)換為 double,但你不能將 Grid<int> 類型的對(duì)象賦值給 Grid<double> 類型的對(duì)象,或從 Grid<int> 構(gòu)造 Grid<double>。以下兩行都無(wú)法編譯:ZBX28資訊網(wǎng)——每日最新資訊28at.com

myDoubleGrid = myIntGrid; // 無(wú)法編譯Grid<double> newDoubleGrid { myIntGrid }; // 無(wú)法編譯

問(wèn)題在于 Grid 模板的拷貝構(gòu)造函數(shù)和賦值運(yùn)算符定義如下:ZBX28資訊網(wǎng)——每日最新資訊28at.com

Grid(const Grid& src);Grid& operator=(const Grid& rhs);

等效于:ZBX28資訊網(wǎng)——每日最新資訊28at.com

Grid(const Grid<T>& src);Grid<T>& operator=(const Grid<T>& rhs);

Grid 的拷貝構(gòu)造函數(shù)和 operator= 都需要一個(gè) const Grid<T>& 的引用。當(dāng)你實(shí)例化 Grid<double> 并嘗試調(diào)用拷貝構(gòu)造函數(shù)和 operator= 時(shí),編譯器生成以下原型的方法:ZBX28資訊網(wǎng)——每日最新資訊28at.com

Grid(const Grid<double>& src);Grid<double>& operator=(const Grid<double>& rhs);

注意,生成的 Grid<double> 類中沒(méi)有接受 Grid<int> 的構(gòu)造函數(shù)或 operator=。ZBX28資訊網(wǎng)——每日最新資訊28at.com

幸運(yùn)的是,您可以通過(guò)向 Grid 類添加模板化的拷貝構(gòu)造函數(shù)和賦值運(yùn)算符的版本來(lái)糾正這種疏忽,從而生成將一個(gè)網(wǎng)格類型轉(zhuǎn)換為另一個(gè)網(wǎng)格類型的方法。以下是新的 Grid 類模板定義:ZBX28資訊網(wǎng)——每日最新資訊28at.com

export template <typename T>class Grid {public:    template <typename E>    Grid(const Grid<E>& src);    template <typename E>    Grid& operator=(const Grid<E>& rhs);    void swap(Grid& other) noexcept;    // 為了簡(jiǎn)潔省略部分內(nèi)容};

原始的拷貝構(gòu)造函數(shù)和拷貝賦值運(yùn)算符不能被移除。如果 E 等于 T,編譯器不會(huì)調(diào)用這些新的模板化拷貝構(gòu)造函數(shù)和模板化拷貝賦值運(yùn)算符。首先查看新的模板化拷貝構(gòu)造函數(shù):ZBX28資訊網(wǎng)——每日最新資訊28at.com

template <typename E>Grid(const Grid<E>& src);

您可以看到有另一個(gè)模板聲明,使用不同的類型名 E(代表“元素”)。類在一個(gè)類型 T 上進(jìn)行模板化,新的拷貝構(gòu)造函數(shù)也在不同的類型 E 上進(jìn)行模板化。這種雙重模板化允許您將一個(gè)類型的網(wǎng)格復(fù)制到另一個(gè)類型。以下是新拷貝構(gòu)造函數(shù)的定義:ZBX28資訊網(wǎng)——每日最新資訊28at.com

template <typename T>template <typename E>Grid<T>::Grid(const Grid<E>& src)    : Grid { src.getWidth(), src.getHeight() } {    // 此構(gòu)造函數(shù)的 ctor-initializer 首先委托給非拷貝構(gòu)造函數(shù)來(lái)分配適當(dāng)?shù)膬?nèi)存量。    // 下一步是復(fù)制數(shù)據(jù)。    for (size_t i { 0 }; i < m_width; i++) {        for (size_t j { 0 }; j < m_height; j++) {            m_cells[i][j] = src.at(i, j);        }    }}

如您所見(jiàn),您必須在成員模板行(帶 E 參數(shù))之前聲明類模板行(帶 T 參數(shù))。您不能像這樣組合它們:ZBX28資訊網(wǎng)——每日最新資訊28at.com

template <typename T, typename E> // 對(duì)于嵌套模板構(gòu)造函數(shù)錯(cuò)誤!Grid<T>::Grid(const Grid<E>& src)

除了構(gòu)造函數(shù)定義之前的額外模板參數(shù)行外,注意您必須使用公共訪問(wèn)方法 getWidth()、getHeight() 和 at() 來(lái)訪問(wèn) src 的元素。那是因?yàn)槟趶?fù)制到的對(duì)象是 Grid<T> 類型的,而您正在復(fù)制的對(duì)象是 Grid<E> 類型的。它們不是同一類型,所以您必須使用公共方法。ZBX28資訊網(wǎng)——每日最新資訊28at.com

swap() 方法實(shí)現(xiàn)如下:ZBX28資訊網(wǎng)——每日最新資訊28at.com

template <typename T>void Grid<T>::swap(Grid& other) noexcept {    std::swap(m_width, other.m_width);    std::swap(m_height, other.m_height);    std::swap(m_cells, other.m_cells);}

模板化賦值運(yùn)算符接受一個(gè) const Grid<E>&,但返回一個(gè) Grid<T>&:ZBX28資訊網(wǎng)——每日最新資訊28at.com

template <typename T>template <typename E>Grid<T>& Grid<T>::operator=(const Grid<E>& rhs) {    // 使用復(fù)制-交換習(xí)慣用法    Grid<T> temp { rhs }; // 在臨時(shí)實(shí)例中完成所有工作。    swap(temp); // 僅通過(guò)非拋出操作提交工作。    return *this;}

這個(gè)賦值運(yùn)算符的實(shí)現(xiàn)使用了復(fù)制-交換習(xí)慣用法。swap() 方法只能交換同一類型的 Grids,但這沒(méi)關(guān)系,因?yàn)檫@個(gè)模板化賦值運(yùn)算符首先使用模板化拷貝構(gòu)造函數(shù)將給定的 Grid<E> 轉(zhuǎn)換為 Grid<T>,名為 temp。之后,它使用 swap() 方法將這個(gè)臨時(shí)的 Grid<T> 與 this(也是 Grid<T> 類型)交換。ZBX28資訊網(wǎng)——每日最新資訊28at.com

使用非類型參數(shù)的方法模板

不同大小網(wǎng)格的賦值和拷貝

在先前的例子中,使用整數(shù)模板參數(shù) HEIGHT 和 WIDTH,主要問(wèn)題是高度和寬度成為了類型的一部分。這種限制阻止了將一個(gè)尺寸的網(wǎng)格賦值給另一個(gè)不同尺寸的網(wǎng)格。然而,在某些情況下,將一個(gè)大小的網(wǎng)格賦值或拷貝給不同大小的網(wǎng)格是可取的。與其使目標(biāo)對(duì)象成為源對(duì)象的完美克隆,不如只從源數(shù)組中復(fù)制適合目標(biāo)數(shù)組的元素,并在源數(shù)組較小的維度上用默認(rèn)值填充目標(biāo)數(shù)組。使用賦值運(yùn)算符和拷貝構(gòu)造函數(shù)的方法模板,您可以做到這一點(diǎn),從而允許賦值和拷貝不同大小的網(wǎng)格。以下是類定義:ZBX28資訊網(wǎng)——每日最新資訊28at.com

export template <typename T, size_t WIDTH = 10, size_t HEIGHT = 10>class Grid {public:    Grid() = default;    virtual ~Grid() = default;    // 明確默認(rèn)拷貝構(gòu)造函數(shù)和賦值運(yùn)算符。    Grid(const Grid& src) = default;    Grid& operator=(const Grid& rhs) = default;    template <typename E, size_t WIDTH2, size_t HEIGHT2>    Grid(const Grid<E, WIDTH2, HEIGHT2>& src);    template <typename E, size_t WIDTH2, size_t HEIGHT2>    Grid& operator=(const Grid<E, WIDTH2, HEIGHT2>& rhs);    void swap(Grid& other) noexcept;    std::optional<T>& at(size_t x, size_t y);    const std::optional<T>& at(size_t x, size_t y) const;    size_t getHeight() const { return HEIGHT; }    size_t getWidth() const { return WIDTH; }private:    void verifyCoordinate(size_t x, size_t y) const;    std::optional<T> m_cells[WIDTH][HEIGHT];};

這個(gè)新定義包括拷貝構(gòu)造函數(shù)和賦值運(yùn)算符的方法模板,以及一個(gè)輔助方法 swap()。注意,非模板化的拷貝構(gòu)造函數(shù)和賦值運(yùn)算符是明確默認(rèn)的(因?yàn)橛脩袈暶髁宋鰳?gòu)函數(shù))。它們僅復(fù)制或賦值源對(duì)象的 m_cells 到目標(biāo)對(duì)象,這正是對(duì)于相同大小的兩個(gè)網(wǎng)格所希望的語(yǔ)義。ZBX28資訊網(wǎng)——每日最新資訊28at.com

下面是模板化拷貝構(gòu)造函數(shù)的實(shí)現(xiàn):ZBX28資訊網(wǎng)——每日最新資訊28at.com

template <typename T, size_t WIDTH, size_t HEIGHT>template <typename E, size_t WIDTH2, size_t HEIGHT2>Grid<T, WIDTH, HEIGHT>::Grid(const Grid<E, WIDTH2, HEIGHT2>& src) {    for (size_t i { 0 }; i < WIDTH; i++) {        for (size_t j { 0 }; j < HEIGHT; j++) {            if (i < WIDTH2 && j < HEIGHT2) {                m_cells[i][j] = src.at(i, j);            } else {                m_cells[i][j].reset();            }        }    }}

請(qǐng)注意,此拷貝構(gòu)造函數(shù)僅從 src 中復(fù)制 x 和 y 維度上的 WIDTH 和 HEIGHT 元素,即使 src 比這更大。如果 src 在任一維度上較小,則額外位置的 std::optional 對(duì)象使用 reset() 方法重置。ZBX28資訊網(wǎng)——每日最新資訊28at.com

下面是 swap() 方法和賦值運(yùn)算符 operator= 的實(shí)現(xiàn):ZBX28資訊網(wǎng)——每日最新資訊28at.com

template <typename T, size_t WIDTH, size_t HEIGHT>void Grid<T, WIDTH, HEIGHT>::swap(Grid& other) noexcept {    std::swap(m_cells, other.m_cells);}template <typename T, size_t WIDTH, size_t HEIGHT>template <typename E, size_t WIDTH2, size_t HEIGHT2>Grid<T, WIDTH, HEIGHT>& Grid<T, WIDTH, HEIGHT>::operator=(    const Grid<E, WIDTH2, HEIGHT2>& rhs) {    // 使用復(fù)制-交換習(xí)慣用法    Grid<T, WIDTH, HEIGHT> temp { rhs }; // 在臨時(shí)實(shí)例中完成所有工作。    swap(temp); // 僅通過(guò)非拋出操作提交工作。    return *this;}

這個(gè)賦值運(yùn)算符的實(shí)現(xiàn)使用了復(fù)制-交換習(xí)慣用法。swap() 方法只能交換相同類型的 Grids,但這是可以的,因?yàn)檫@個(gè)模板化賦值運(yùn)算符首先使用模板化拷貝構(gòu)造函數(shù)將給定的 Grid<E, WIDTH2, HEIGHT2> 轉(zhuǎn)換為 Grid<T, WIDTH, HEIGHT>,稱為 temp。之后,它使用 swap() 方法交換這個(gè)臨時(shí) Grid<T, WIDTH, HEIGHT> 和 this。ZBX28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-46477-0.html玩轉(zhuǎn)C++方法模板,編程技能秒提升

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 自己動(dòng)手寫數(shù)據(jù)庫(kù):解析 Select 語(yǔ)句并生成查詢樹(shù)

下一篇: 數(shù)據(jù)結(jié)構(gòu):Vec&lt;T&gt;、&amp;[T]、Box&lt;[T]&gt; ,你真的了解集合容器么?

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 天貓精靈Sound Pro體驗(yàn):智能音箱沒(méi)有音質(zhì)?來(lái)聽(tīng)聽(tīng)我的

    這幾年除了手機(jī)作為智能生活終端最主要的核心之外,第二個(gè)可以成為中心點(diǎn)的產(chǎn)品是什么?——是智能音箱。 手機(jī)在執(zhí)行命令的時(shí)候有兩種操作方式,手和智能語(yǔ)音助手,而智能音箱只
  • vivo TWS Air開(kāi)箱體驗(yàn):真輕 臻好聽(tīng)

    在vivo S15系列新機(jī)的發(fā)布會(huì)上,vivo的最新款真無(wú)線藍(lán)牙耳機(jī)vivo TWS Air也一同發(fā)布,本次就這款耳機(jī)新品給大家?guī)?lái)一個(gè)簡(jiǎn)單的分享。外包裝盒上,vivo TWS Air保持了vivo自家產(chǎn)
  • Golang 中的 io 包詳解:組合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是對(duì)Reader和Writer接口的組合,
  • 如何正確使用:Has和:Nth-Last-Child

    我們可以用CSS檢查,以了解一組元素的數(shù)量是否小于或等于一個(gè)數(shù)字。例如,一個(gè)擁有三個(gè)或更多子項(xiàng)的grid。你可能會(huì)想,為什么需要這樣做呢?在某些情況下,一個(gè)組件或一個(gè)布局可能會(huì)
  • 得物效率前端微應(yīng)用推進(jìn)過(guò)程與思考

    一、背景效率工程隨著業(yè)務(wù)的發(fā)展,組織規(guī)模的擴(kuò)大,越來(lái)越多的企業(yè)開(kāi)始意識(shí)到協(xié)作效率對(duì)于企業(yè)團(tuán)隊(duì)的重要性,甚至是決定其在某個(gè)行業(yè)競(jìng)爭(zhēng)中突圍的關(guān)鍵,是企業(yè)長(zhǎng)久生存的根本。得物
  • 之家push系統(tǒng)迭代之路

    前言在這個(gè)信息爆炸的互聯(lián)網(wǎng)時(shí)代,能夠及時(shí)準(zhǔn)確獲取信息是當(dāng)今社會(huì)要解決的關(guān)鍵問(wèn)題之一。隨著之家用戶體量和內(nèi)容規(guī)模的不斷增大,傳統(tǒng)的靠"主動(dòng)拉"獲取信息的方式已不能滿足用
  • iQOO Neo8系列或定檔5月23日:首發(fā)天璣9200+ 安卓跑分王者

    去年10月,iQOO推出了iQOO Neo7系列機(jī)型,不僅搭載了天璣9000+,而且是同價(jià)位唯一一款天璣9000+直屏旗艦,一經(jīng)上市便受到了用戶的廣泛關(guān)注。在時(shí)隔半年后,
  • OPPO K11搭載高性能石墨散熱系統(tǒng):旗艦同款 性能涼爽釋放

    日前OPPO官方宣布,將于7月25日14:30舉辦新品發(fā)布會(huì),屆時(shí)全新的OPPO K11將正式與大家見(jiàn)面,將主打旗艦影像,和同檔位競(jìng)品相比,其最大的賣點(diǎn)就是將配備索尼
  • 電博會(huì)與軟博會(huì)實(shí)現(xiàn)"線下+云端"的雙線融合

    在本次“電博會(huì)”與“軟博會(huì)”雙展會(huì)利好條件的加持下,既可以發(fā)揮展會(huì)拉動(dòng)人流、信息流、資金流實(shí)現(xiàn)快速交互流動(dòng)的作用,繼而推動(dòng)區(qū)域經(jīng)濟(jì)良性發(fā)展;又可以聚
Top 主站蜘蛛池模板: 泊头市| 伊通| 汾阳市| 乾安县| 凉城县| 武隆县| 萍乡市| 确山县| 长沙市| 大石桥市| 鞍山市| 临洮县| 饶平县| 大城县| 禹州市| 大方县| 南郑县| 武平县| 沂水县| 乐至县| 比如县| 铜川市| 蓝田县| 盐津县| 辽阳县| 定西市| 镇安县| 荔波县| 汝城县| 韶关市| 邮箱| 莎车县| 新源县| 洪泽县| 东乌珠穆沁旗| 涡阳县| 大关县| 苏尼特右旗| 滕州市| 淮滨县| 西林县|