1. 程式人生 > >c/c++模板的定義和實現分開的問題(一)

c/c++模板的定義和實現分開的問題(一)

注意c/c++模板的定義和實現- -

定義一個類一般都是在標頭檔案中進行類宣告,在cpp檔案中實現,但使用模板時應注意目前的C++編譯器還無法分離編譯,最好將實現程式碼和宣告程式碼均放在標頭檔案中。如:

test.h

template<class T>class CTest{ public:    T& GetValue();    void SetValue(const T& _Value);protected:    T m_Value; };

test.cpp

template<class T>T& CTest<T>::GetValue(){     return m_Value; }template<class T>void CTest<T>::SetValue(const T& _Value){     m_Value = _Value; }


在這兒test.cpp中的內容應放在test.h中,否則在生成最終可執行程式時就會出現錯誤(在連結時會出錯)。因為在編譯時模板並不能生成真正的二進位制程式碼,而是在編譯呼叫模板類或函式的CPP檔案時才會去找對應的模板宣告和實現,在這種情況下編譯器是不知道實現模板類或函式的CPP檔案的存在,所以它只能找到模板類或函式的宣告而找不到實現,而只好建立一個符號寄希望於連結程式找地址。但模板類或函式的實現並不能被編譯成二進位制程式碼,結果連結程式找不到地址只好報錯了。

《C++程式設計思想》第15章(第300頁)說明了原因:模板定義很特殊。由template<…>處理的任何東西都意味著編譯器在當時不為它分配儲存空間,它一直處於等待狀態直到被一個模板例項告知。在編譯器和聯結器的某一處,有一機制能去掉指定模板的多重定義。所以為了容易使用,幾乎總是在標頭檔案中放置全部的模板宣告和定義。


沈公子在 2005年2月15日11:19星期二 評論: 
你說的有誤,要將實現程式碼放在cpp檔案中,否則編譯時所有包含標頭檔案的單元都要額外的編譯時間。
只要在實現中的模板函式之前加上export就可以避免你說的連結錯誤,這是STL程式設計時的技巧之一。

相關推薦

C++ 學習筆記 變數基本型別

C++ 學習筆記 一、變數和基本型別概述 型別是所有程式的基礎。型別告訴我們資料代表什麼意思以及可以對資料執行哪些操作。 c++基本型別: 字元型 整型 浮點型 c++ 還提供了可用於自定義資料型別的機制,標準庫正式利用了這些機制定義了許多更復雜的型別,比如可變長字串string 和vector等。此外,

effective C++筆記--模板與泛型程式設計

文章目錄 瞭解隱式介面和編譯器多型 瞭解typename的雙重意義 學習處理模板化基類內的名稱 將與引數無關的程式碼抽離template 瞭解隱式介面和編譯器多型 . 面向物件程式設計世界總是以顯式介面和執行期多型解決問題。比

定義ImageView實現地圖

  現在一提到地圖很多人就會想到百度地圖高德地圖等SDK,但是公司遇到個專案要做到室內導航,現在的第三方用GPS定位又不準,所以使用了一個自定義的ImageView去實現地圖的功能。該地圖有導航、定位、分級顯示、點選檢視位置詳細資訊的功能。今天我們先說下基礎地圖資料的顯示及

c/c++模板定義實現分開的問題

注意c/c++模板的定義和實現- -定義一個類一般都是在標頭檔案中進行類宣告,在cpp檔案中實現,但使用模板時應注意目前的C++編譯器還無法分離編譯,最好將實現程式碼和宣告程式碼均放在標頭檔案中。如:test.htemplate<class T>class CT

C++模板應用——讓模板定義實現分離的方法

關於c++中類的模板,慣常的用法都是把實現和定義放在標頭檔案裡了事。這樣的問題是,加大了標頭檔案的長度,減低了模板程式碼的可讀性,還有就是破壞了面向物件的隱藏實現的規則。下面就是這種問題的兩個解決方案的總結。 假設模板程式碼如下:  1 // 模板定義 a.h  2 #in

C++模板定義實現分離導致的編譯錯誤

今天在實現一個二叉樹的時候,用到了模板,沒在意,和平時一樣寫了兩個檔案:BinaryTree.h,BinaryTree.cpp。思路和平時一樣,h檔案中定義了模板類,然後在cpp檔案中實現了一些功能函式。 然後在test.cpp中測試,遇到了一些問題、 問題

C#基礎知識-函數的定義調用

返回 {0} string 訪問修飾符 容器 列表 rdquo 所有 func 函數也可以稱為方法,可以很方便的把一些行為封裝到函數裏面,當調用這一函數時會把函數塊裏面的代碼按照順序執行,方法可以有多種形式,有無參數,有無返回值等。 1. 函數的定義 函數定

C之單引號雙引號十三

C語言 單引號 雙引號 在 C 語言中,我們會經常使用到單引號和雙引號。那麽單引號用來表示字符字面量,雙引號是用來表示字符串字面量。 'a' 表示字符字面量,在內存中占1個字節; 'a' + 1表示 'a' 的 ASCI

C#多線程異步——一些異步編程模式

img rar 效率 釋放 http 調用 完成 引用 iar 一、任務並行庫   任務並行庫(Task Parellel Library)是BCL中的一個類庫,極大地簡化了並行編程,這裏以Parallel.For和Parallel.ForEach為例。在C#中for/fo

C++ 實現反射

反射,就是根據一個類名,即可根據類名獲取類資訊,建立新物件。反射在很多語言都天然支援,然而不包括 C++,但我們肯定會經常遇到這種根據類名生成物件的場景,這就需要我們自己動手來實現了。反正 C++ 這麼強大,一定沒有問題 :) version 1 我們略做思考,就可以想到一種最簡

C#裝箱,拆箱強制轉換

出處:https://www.cnblogs.com/fengjiulin110120/p/6605739.html 關係: 強制轉換就包含有裝箱拆箱操作,裝箱就是把值型別轉換成引用型別,反之就是拆箱.   一:  裝箱和拆箱: 裝箱是把值型別轉換成引用型別,而拆箱是把引用型別轉換成值型別

C++ Primer Plus》學習筆記——第五章 迴圈關係表示式

本章內容: for迴圈和while迴圈 表示式和語句 運算子組合 複合語句 逗號運算子以及關係運算符 typedef工具 字元輸入方法get() 檔案尾條件 巢狀迴圈和二維陣列 計算機除了儲存資料外,還可以做很多其他工作。可以對資料進

C++學習之迴圈關係表示式1

在c語言中我這部分還算學習的挺好,所以這部分我只新增一些我不太懂的點: 1.通常,cout在顯示bool值之前將它們轉換為int,但是在前面使用cout.setf(ios:boolalpha)函式呼叫設定了一個標記,該標記命令cout顯示true和false,而不是1和0;

C++ Primer Plus--迴圈關係表示式

C++提供三種迴圈:for迴圈、while迴圈和do while迴圈。 5.1 for迴圈 int i; for (i = 0; i < 5; i++) cout << "C++ knows loops.\n"; 該迴圈首先將整數變數i設定

effective C++筆記--模板與泛型程式設計

文章目錄 請使用traits classes表現型別資訊 認識模板超程式設計 請使用traits classes表現型別資訊 . traits並不是C++的關鍵字或是預先定義好的構件,它們是一種技術,也是一個C++程式設計師共同遵守的協議

effective C++筆記--模板與泛型程式設計

文章目錄 運用成員函式模板接受所有相容型別 需要型別轉換時請為模板定義非成員函式 運用成員函式模板接受所有相容型別 . 真實指標做的很好的一件事是支援隱式轉換,派生類的指標可以指向基類的指標,指向非常量物件的指標可以指向轉換成常量物件的指

C語言變數定義與資料溢位初學者

1、變數定義的一般形式為:型別說明符、變數名識別符號等;例:int a,b,c;(abc為整型變數) 在書寫變數定義時應注意以下幾點: (1)允許在一個型別說明符後,定義多個相同型別的變數。各變數之間用“,”間隔。型別說明符與變數名之間用一個空格間隔。 (2)最後一個變數之後必須以“;”結尾。 (3)

C++ Primer Plus》學習筆記——第六章 分支語句邏輯運算子

本章內容包括: if 語句 if else 語句 邏輯運算子 &&、||和! cctype字元函式庫 條件運算子: ? : switch 語句 continue和break語句 讀取數字的迴圈 基本檔案輸入和輸出 if 語句 if (tes

C/C++:各種基本演算法實現小結—— 圖及其遍歷

各種基本演算法實現小結(四)—— 圖及其遍歷 (均已測試通過) ==================================================================== 圖——深度優先和廣度優先演算法 無向圖

C/C++:各種基本演算法實現小結—— 單鏈表

各種基本演算法實現小結(一)—— 單鏈表 (均已測試通過) ============================================================ 單鏈表(測試通過) 測試環境: Win-TC