衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

模版定義一定要寫在頭文件中嗎?

汽車電子技術 ? 來源:程序喵大人 ? 作者:程序喵大人 ? 2023-02-21 14:23 ? 次閱讀

大家在使用C++代碼時或多或少都會使用到模板,使用模板時應該都是把定義放在了頭文件中,因為放在源文件中定義會編譯失敗。

那問題來了,模板中的函數定義一定要寫在頭文件中嗎?

先說結論:不一定要放在頭文件中,定義也可以放在源文件中,但操作起來還是有點麻煩的。

繼續往下看看

先看一段正常的模板代碼:

// template.h
#include 


template <typename T>
struct TemplateTest {
    T value;
    void func();
};


template <typename T>
void TemplateTest::func() {
    std::cout << typeid(T).name() << std::endl;
}


// test_template.cc
#include "template.h"


int main() {
    TemplateTest<int> test;
    test.func();
    return 0;
}

這段代碼沒啥毛病,因為實現放在了頭文件中,也會正常輸出。

如果我把函數定義放在源文件中呢,會怎么樣?

// template.h
#include 


template <typename T>
struct TemplateTest {
    T value;
    void func();
};


// template.cc
template <typename T>
void TemplateTest::func() {
    std::cout << typeid(T).name() << std::endl;
}


// test_template.cc
#include "template.h"


int main() {
    TemplateTest<int> test;
    test.func();
    return 0;
}

嗯,不出意外,編譯報錯了,報了個沒有某個函數實現的error:

/tmp/ccPghOjU.o: In function `main':
test_template.cc:(.text+0x1f): undefined reference to `TemplateTest::func()'
collect2: error: ld returned 1 exit status

為什么沒有此函數定義?

先補充個基礎知識,模板的本質。本質其實就是類型泛化,可以用一個T代替多種類型,對于上面的模板,假如有此種使用:

TemplateTest<int> test;

那模板最終可能變成這樣:

struct TemplateTest_int {
    int value;
    void func() {
        std::cout << typeid(int).name() << std::endl;
    }
};

如果有這兩種使用:

TemplateTest test;
TemplateTest<float> test;

那模板最終可能會變成這樣:

struct TemplateTest_int {
    int value;
    void func() {
        std::cout << typeid(int).name() << std::endl;
    }
};


struct TemplateTest_float {
    float value;
    void func() {
        std::cout << typeid(float).name() << std::endl;
    }
};

模板最終會展開成什么樣,取決于用戶是怎么使用它的。

那回到上面的問題,為什么把定義放在源文件中,編譯就失敗了呢,因為每個源文件的編譯都是獨立的,盡管在test_template.cc進行了TemplateTesttest的使用,但是在template.cc中卻感知不到,所以也就沒法定義相關的實現。

思路來了,只需要讓template.cc中感知到T有int類型的情況,那編譯應該就沒問題。這里有個語法,叫模板實例化,像這樣:

template struct TemplateTest<int>;

把這行代碼放在template.cc中:

// template.cc
#include "template.h"


template <typename T>
void TemplateTest::func() {
    std::cout << typeid(T).name() << std::endl;
}


template struct TemplateTest<int>;

整個代碼的編譯就沒得問題了,通過這種方式即可以實現模板函數聲明與實現的分離。

這也印證了上面的結論。

這里我再拋出 幾個問題 ,大家可以討論討論:

  • 模板的使用是否會導致代碼段體積增大?怎么解決?
  • 模板的函數定義放在了頭文件中,好多個源文件都include此頭文件,是否會導致函數的multi definition類型的鏈接報錯?實際使用中貌似沒有報錯,為什么?大家有想過嗎?
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C++
    C++
    +關注

    關注

    22

    文章

    2114

    瀏覽量

    73856
  • 頭文件
    +關注

    關注

    0

    文章

    25

    瀏覽量

    9901
  • 源文件
    +關注

    關注

    0

    文章

    30

    瀏覽量

    4612
收藏 人收藏

    評論

    相關推薦

    Linux下個實用的頭文件

    queue.h是Linux、FreeBSD頭文件
    發表于 12-02 11:48 ?932次閱讀

    modelsim中一定要寫testbench文件嗎?

    modelsim中一定要寫testbench文件嗎?
    發表于 03-29 10:02

    定義下的“GPIO_”是什么作用,一定要用嗎

    #defineGPIO_KEY P1//獨立鍵盤用P1口#defineGPIO_LED P0//led使用P0口我想知道這個宏定義下的“GPIO_”是什么作用,一定要用嗎?c程序的GPIO_與通訊輸入\輸出的GPIO是同
    發表于 05-29 12:22

    頭文件定義全局變量的方法

      教大家個如何在頭文件定義全局變量的方法  通常情況下,都是在C文件
    發表于 07-04 08:34

    頭文件定義全局變量的方法介紹

      教大家個如何在頭文件定義全局變量的方法  通常情況下,都是在C文件
    發表于 07-09 09:25

    教大家個如何在頭文件定義全局變量的方法

    通常情況下,都是在C文件定義全局變量,在頭文件聲明,但是,如果我們定義的全局變量需要被很多的
    發表于 12-04 14:55 ?19次下載

    編程引用頭文件的幾種方法及要點

    好的編程習慣,會直接影響代碼的質量,在嵌入式C/C++頭文件的引用方式和方法有多種,同時些細節也會影響你代碼質量和編譯效率。 下面就來說說與頭文件有關的知識; 1 引號“”和尖括
    的頭像 發表于 03-12 17:30 ?3418次閱讀

    在keil創立頭文件

    定義格式#ifndef _LED_H_#define _LED_H_ //跟在后面的_LED_H_只是文件名//內容#endif用51單片機舉例注意在頭文件
    發表于 11-21 14:06 ?2次下載
    在keil<b class='flag-5'>中</b>創立<b class='flag-5'>一</b>個<b class='flag-5'>頭文件</b>

    keil添加了頭文件仍然報找不到頭文件的原因

    ,則需要重新將文件夾包含到工程。4)點擊魔術棒的C/C++,將包含該頭文件的最內層文件夾包含進去,
    發表于 11-21 14:21 ?13次下載
    keil添加了<b class='flag-5'>頭文件</b>仍然報找不到<b class='flag-5'>頭文件</b>的原因

    單片機-頭文件

    reg52.h頭文件的作用在代碼引用頭文件,其實際意義是將頭文件的所用內容都放到引用頭文件
    發表于 11-23 17:21 ?17次下載
    單片機-<b class='flag-5'>頭文件</b>

    MCU_頭文件編寫

    頭文件般放些重復使用的代碼,如:常量、變量、宏等的定義,函數的聲明。當使用#include語句引用頭頭文件時,相當于將
    發表于 12-05 10:36 ?5次下載
    MCU_<b class='flag-5'>頭文件</b>編寫

    【筆記】單片機頭文件的順序會讓程序報錯?

    頭文件的正確順序主要涉及以下幾個方面:1.依賴關系和聲明順序:在編寫單片機程序時,可能會有頭文件之間存在依賴關系。某些頭文件
    的頭像 發表于 05-19 09:50 ?1643次閱讀
    【筆記】單片機<b class='flag-5'>頭文件</b>的順序會讓程序報錯?

    什么是頭文件頭文件編寫的般格式要求是怎樣?

    本文介紹頭文件定義、編寫、保存及引用等方面的內容,包括了般的格式要求、例程等。
    的頭像 發表于 11-08 16:25 ?1885次閱讀
    什么是<b class='flag-5'>頭文件</b>?<b class='flag-5'>頭文件</b>編寫的<b class='flag-5'>一</b>般格式要求是怎樣?

    請問頭文件能不能定義變量呢?

    最近在編譯個工程的時候,突然遇到了變量重復定義的問題,根據提示打開這幾個 C 文件,并沒有發現定義變量的地方。后來再找找,原來變量
    的頭像 發表于 04-28 09:33 ?1268次閱讀

    可重復頭文件的固定結構

    年輕人,你可曾記得,在修習C語言的時候,見過這樣的字句:在創建頭文件的時候,一定要加入保護宏。
    的頭像 發表于 08-29 10:23 ?404次閱讀
    可重復<b class='flag-5'>頭文件</b>的固定結構
    视频百家乐信誉| 百家乐官网视频下载| 百家乐赌经| 免费百家乐官网规则| 蓝盾百家乐具体玩法| 百家乐官网两边| 大发888国际娱乐网| 百家乐官网发牌| 松潘县| 百人百家乐软件供应| 澳门百家乐官网威尼斯| 大发888 dafa888 gzsums| 做生意的信风水吗| 鹤庆县| 网络百家乐路单图| 玩百家乐官网高手支招篇| 大发888怎么注册账号| 建湖县| 太阳城真人娱乐城| 百家乐网上公式| 百家乐官网信誉好的平台| 大发888在线开户| 澳门百家乐有哪些| 菲律宾百家乐官网开户| 竞彩足球| 包赢百家乐的玩法技巧和规则| 七胜百家乐官网赌场娱乐网规则 | 百家乐官网筹码真伪| 赌场风云2| 威尼斯人娱乐城线路lm0| 百家乐软件l柳州| 百家乐官网开过的路纸| 北京太阳城老年公寓| gt百家乐平台| 百家乐官网赌博策略| 漳州市| 大发888游戏平台88| 网络百家乐怎么作弊| 百家乐官网娱乐网址| 百家乐官网蓝盾假网| 大发888娱乐场1888|