-
當前位置:首頁 > 創(chuàng)意學(xué)院 > 營銷推廣 > 專題列表 > 正文
類模板的實例化在編譯時進行(類模板的實例化在編譯時進行的操作)
大家好!今天讓創(chuàng)意嶺的小編來大家介紹下關(guān)于類模板的實例化在編譯時進行的問題,以下是小編對此問題的歸納整理,讓我們一起來看看吧。
開始之前先推薦一個非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計劃、工作報告、論文、代碼、作文、做題和對話答疑等等
只需要輸入關(guān)鍵詞,就能返回你想要的內(nèi)容,有小程序、在線網(wǎng)頁版、PC客戶端和批量生成器
官網(wǎng):https://ai.de1919.com。
本文目錄:
求高人解決C++練習(xí)?急用,先謝謝了!
BBCBDCBAAA其中第18題內(nèi)容說法有疑問
21 *(--p)
22 復(fù)制或者拷貝
23 新
24 基類的構(gòu)造函數(shù)
25 構(gòu)造 析構(gòu)
C++模板:這個程序為什么通不過編譯(C++11)
1):我們將testTemplate.cpp文件從工程中拿掉,即刪除testTemplate.cpp的定義。然后直接編譯上面的文件,能編譯通過。這說明編譯器在展開testTemplate.h后編譯main.cpp文件的時候并沒有去檢查模板類的實現(xiàn)。它只是記住了有這樣的一個模板聲明。由于沒有調(diào)用模板的成員函數(shù),編譯器鏈接階段也不會在別的obj文件中去查找類模板的實現(xiàn)代碼。因此上面的代碼沒有問題。2):把main.cpp文件中,第7行的注釋符號去掉。即加入類模板的實例化代碼。在編譯工程,會發(fā)現(xiàn)也能夠編譯通過?;叵胍幌逻@個過程,testTemplate.h被展開,也就是說main.cpp在編譯是就能找到MyClass<T>的聲明。那么,在編譯第7行的時候就能正常的實例化一個類模板出來。這里注意:類模板的成員函數(shù)只有在調(diào)用的時候才會被實例化。因此,由于沒有對類模板成員函數(shù)的調(diào)用,編譯器也就不會去查找類模板的實現(xiàn)代碼。所以,上面的函數(shù)能編譯通過。
3):把上面第10行的代碼注釋符號去掉。即加入對類模板成員函數(shù)的調(diào)用。這個時候再編譯,會提示一個鏈接錯誤。找不到printValue的實現(xiàn)。道理和上面只有函數(shù)的聲明,沒有函數(shù)的實現(xiàn)是一樣的。即,編譯器在編譯main.cpp第10行的時候發(fā)現(xiàn)了對myClass.PrintValue的調(diào)用,這時它在當前文件內(nèi)部找不到具體的實現(xiàn),因此會做一個標記,等待鏈接器在其他的obj文件中去查找函數(shù)實現(xiàn)。同樣,連接器也找不到一個包括MyClass<T>::PrintValue聲明的obj文件。因此報告鏈接錯誤。
4):既然是由于找不到testTemplate.cpp文件,那么我們就將testTemplate.cpp文件包含在工程中。再次編譯,在VS中會提示一個鏈接錯誤,說找不到外部類型_thiscall MyClass<int>::PrintValue(int)。也許你會覺得很奇怪,我們已經(jīng)將testTemplate.cpp文件包含在了工程中了阿。先考慮一個問題,我們說過模板的編譯實際上是一個實例化的過程,它并不編譯產(chǎn)生二進制代碼。另外,模板成員函數(shù)也只有在被調(diào)用的時候才會初始化。在testTemplate.cpp文件中,由于包含了testTemplate.h頭文件,因此這是一個獨立的可以編譯的類模板。但是,編譯器在編譯這個testTemplate.cpp文件的時候由于沒有任何成員函數(shù)被調(diào)用,因此并沒有實例化PrintValue成員。也許你會說我們在main.cpp中調(diào)用了PrintValue函數(shù)。但是要知道testTemplate.cpp和main.cpp是兩個獨立的編譯單元,他們相互間并不知道對方的行為。因此,testTemplate.cpp在編譯的時候?qū)嶋H上還是只編譯了testTemplate.h中的內(nèi)容,即再次聲明了模板,并沒有實例化PrintValue成員。所以,當main.cpp發(fā)現(xiàn)需要PrintValue成員,并在testTemplate.obj中去查找的時候就會找不到目標函數(shù)。從而發(fā)出一個鏈接錯誤。
5):由此可見,模板代碼不能按照常規(guī)的C/C++代碼來組織。必須得保證使用模板的函數(shù)在編譯的時候就能找到模板代碼,從而實例化模板。在網(wǎng)上有很多關(guān)于這方面的文章。主要將模板編譯分為包含編譯和分離編譯。其實,不管是包含編譯還是分離編譯,都是為了一個目標:使得實例化模板的時候就能找到相應(yīng)的模板實現(xiàn)代碼。大家可以參照這篇文章。
最后,作一個小總結(jié)。C++應(yīng)用程序的編譯一般要經(jīng)歷展開頭文件->編譯cpp文件->鏈接三個階段。在編譯的時候如果需要外部類型,編譯器會做一個標記,留待連接器來處理。連接器如果找不到需要的外部類型就會發(fā)生鏈接錯誤。對于模板,單獨的模板代碼是不能被正確編譯的,需要一個實例化器產(chǎn)生一個模板實例后才能編譯。因此,不能寄希望于連接器來鏈接模板的成員函數(shù),必須保證在實例化模板的地方模板代碼是可見的。
C# 類的實例化是在 編譯時 還是 運行時發(fā)生的?
同上,正確答案是在運行時,NET程序在編譯的時候是由編譯器把C#代碼轉(zhuǎn)換成MSIL(微軟中間代碼),此時僅僅是對代碼進行了修改
在程序第一次運行的時候CLR(公共語言運行時)根據(jù)本地硬件特征編譯生成最優(yōu)化的二進制文件,存放在C盤對應(yīng)版本的NET的緩存中,
之后才會調(diào)用CPU執(zhí)行,執(zhí)行的時候,如果遇到new關(guān)鍵字,才會在內(nèi)存中實例化對象開辟空間
也就是說,在程序沒有執(zhí)行之前,代碼還是代碼,new都沒有調(diào)用
以上就是關(guān)于類模板的實例化在編譯時進行相關(guān)問題的回答。希望能幫到你,如有更多相關(guān)問題,您也可以聯(lián)系我們的客服進行咨詢,客服也會為您講解更多精彩的知識和內(nèi)容。
推薦閱讀:
類模板的實例化在編譯時進行(類模板的實例化在編譯時進行的操作)
抖音直播同行付費流量怎么算(抖音直播同行付費流量怎么算出來的)