1. 程式人生 > >模板類h和cpp分開寫問題淺析

模板類h和cpp分開寫問題淺析

.h檔案

#pragma once

template<class T>
class Person
{
public:
    Person(T age);
    void Show();
public:
    T age;
};

.cpp檔案

#include "Person.h"

template<class T>
Person<T>::Person(T age)
{
    this->age = age;
}

template<class T>
void Person<T>::Show()
{
    cout
<< "Age:" << age << endl; }

main.cpp

#include<iostream>

#include "Person.h"

using namespace std;

int main()
{
    Person<int>p(10);
    p.Show();

    return 0;
}

此時編譯出現錯誤:

錯誤 1 error LNK2019: 無法解析的外部符號 “public: __thiscall Person::Person(int)” ([email protected]

@@[email protected]@Z),該符號在函式 _main 中被引用 \程式碼\模板類h和cpp分開寫\模板類h和cpp分開寫.obj 模板類h和cpp分開寫

錯誤 2 error LNK2019: 無法解析的外部符號 “public: void __thiscall Person::Show(void)” ([email protected][email protected]@@QAEXXZ),該符號在函式 _main 中被引用 \程式碼\模板類h和cpp分開寫\模板類h和cpp分開寫.obj 模板類h和cpp分開寫

錯誤 3 error LNK1120: 2 個無法解析的外部命令\程式碼\test01\Debug\模板類h和cpp分開寫.exe 1 1 模板類h和cpp分開寫

而註釋掉Personp(10);p.Show();後編譯成功
問題分析:
這和c++編譯機制和模板實現機制有關。
c++是獨立編譯,例如a.cpp、b.cpp、c.cpp三個檔案,先獨立編譯成三個獨立的目標檔案,即a.o、b.o、c.o,然後再通過連結器連結起來,生成可執行檔案。
在編譯時,a.cpp發現一個函式呼叫,在當前檔案找不到函式定義,則在函式位置生成符號,在連結時,再尋找這個函式。
模板是兩次編譯。第一次編譯時只對模板進行編譯,不生成具體函式,在呼叫時才生成具體函式。

所以在這個專案中,編譯main.cpp時,會編譯Person.h,而Person.h裡只有函式宣告,不進行編譯。則在連結器尋找函式時,因為尋找不到函數出現錯誤。而Person.cpp編譯時,函式模板只進行第一次編譯,因為沒有具體使用,所以沒有進行第二次編譯,沒有生成具體函式。所以在main.cpp連結時,因為尋找不到函數出現錯誤。

改正:
在main.cpp中將#include “Person.h”替換為#include “Person.cpp”.

所以在寫類模板時,宣告和定義寫在一個檔案裡。檔案字尾為hpp!

相關推薦

模板hcpp分開問題淺析

.h檔案 #pragma once template<class T> class Person { public: Person(T age); void Show(); public: T age; }; .cp

C++模板中宣告定義是否可以分開存放在.h.cpp檔案中

        雖然我們遇到的絕大多數情況下,模板中函式的宣告和定義都放在標頭檔案中,但我想肯定有人和我一樣,想知道是否可以分開存放。動手實驗後,會發現有的可以,有的會報錯,其實,這和編譯器有關。         要弄清楚這個問題,首先要解決兩個問題。         第一

模板hcpp分離編寫(補充)

demo.cpp檔案 #define _CRT_SECURE_NO_WARNINGS #include "Person.hpp"//如果是Person.h就連結失敗 類模板一般不分開寫 int mai

面向物件程式設計之.h.cpp檔案分開編寫

對於一個小程式,一般不需要編寫標頭檔案,但是對於一個複雜的大專案,模組化編寫程式,便於理解,且容易下手,將問題分解成一小塊一小塊,逐個擊破: 抽象一個點,一個圓,並判斷點與圓的關係。(在圓內還是圓外)

不能將模板的宣告與實現分開

今天用類模型實現一個linklist,開始是.h和.cpp將類模板的宣告與實現分開寫的,結果總是報錯: 擺弄了半個小時都不知道為啥,結果一百度,原來類模板的宣告與實現是不能夠分開寫的。 《C++程式設計思想》第15章(第300頁)說明了原因: 模板定義

新建ui文件及相應.h.cpp文件

creator .cpp 技術分享 tle title inf 新建 文件夾 目的 1.在Qt Creator中新建一個任意的項目(如untitled); 2.在該項目中添加QT設計師界面類; 3.將新建的3個文件(.ui、.h、.cpp)拷貝到目標項目文件夾中;

巨集定義在.h.cpp中的差別

在mac os x 10.6  xcode4.2環境中遇到一個堆疊被破壞的bug,問題重現: xcode中lib工程A,有類 classA{ int m_nj; #define _DEBUG int m_ni; #endif } classA::class

jspjs分開,在js中無法通過el表示式取後臺model傳遞過來的值

原因:在jsp檔案中可以引入EL對應的標籤庫,但在JS檔案中是無法引入的 解決辦法: EL表示式不能用於js檔案中,一般用於jsp檔案,但可用於jsp檔案中的js程式碼裡, 所以解

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

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

【轉】.h.cpp檔案的區別

首先,所有的程式碼是都可以放在一個cpp檔案裡面的。這對電腦來說沒有任何區別, 但對於一個工程來說,臃腫的程式碼是一場災難,非常不適合閱讀和後期維護, 所以.h和.cpp檔案更多的是對程式設計師的編寫習慣進行規範 用法 1、.h檔案直接#include到需要的.c

C++中為什麼要標頭檔案原始檔分開呢?

對c&c++程式來說,基本上來說都是要把原始檔和標頭檔案分別編寫。一般都是代表一個基本功能的原始檔引用相應的標頭檔案。 一個 相關功能的模組可能有若干對原始檔和標頭檔案組成。這是基於元件程式設計的核心。 在我看來,他的好處是巨大的,是java不可比擬的,也是

C++中的 .h .cpp 區別詳解

在C++程式設計過程中,隨著專案的越來越大,程式碼也會越來越多,並且難以管理和分析。於是,在C++中就要分出了頭(.h)檔案和實現(.cpp)檔案,並且也有了Package的概念。 對於以C起步,C#作為“母語”的我剛開始跟著導師學習C++對這方面還是感到很模糊。雖然我

STL中的模板pair map

STL的<utility>標頭檔案中描述了一個非常簡單的模板類pair,用來表示一個二元組或元素對,並提供了大小比較的比較運算子模板函式。 pair模板類需要兩個引數:首元素的資料型別和尾元素的資料型別。pair模板類物件有兩個成員:first和second,分

C++中模板宣告實現能否分離?

1.宣告部分 //point.h #ifndef _POINT_ #define _POINT_ template<class Elem> class Point { public: Point(Elem); } ; #endif 2.實現部分

模板的聲明定義都到頭文件中,可以分到多個.h文件中

測試 blog alt com src 類的聲明 技術 寫到 nbsp 通常類模板的聲明和定義都寫到頭文件中,那麽為了看著清晰,類的聲明和定義可以分開寫到多個頭文件中嗎,測試: 類模板的聲明和定義都寫到頭文件中,可以分到多個.h文件中

為什麼模板模板成員函式不能分檔案(.h與.cpp

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

為什麽C++中聲明定義要分開

使用 還得 開始 階段 怎麽辦 clu 即使 tip 文件中 現在開始寫項目了,你會發現我們一般都要寫一個cpp,對應的還得有一個h文件,那麽為什麽在C++中我們要這麽做? .h就是聲明,.cpp就是實現,而所謂分離式實現就是指“聲明”和“定義”分別保存在不同的文件中,聲明

C++模板頭文件實現文件分離

證明 about compile strong 驗證 title htm -c itl http://www.cnblogs.com/lvdongjie/p/4288373.html 如何實現C++模板類頭文件和實現文件分離,這個問題和編譯器有關。 引用<<

逆向第十九講——繼承成員、運算符重載、模板逆向20171211

指針 emp 繼承方式 virtual n) stp 定義 調試 不同的 一、類繼承逆向 在C++中使用到繼承,主要是為了實現多態,那麽多態就必須會用到虛函數,即會產生虛表指針。 (1)父類和子類中有沒用到虛函數的四種情形 1)父類和子類中都沒有用到

c++中模板的實現(模板模板函數)

c++ 模板實例化 泛型編程 [TOC] 模板  當我們實現一個交換函數時,我們可以寫成如下。 void Swap(int& x, int& y) { int tmp = x; x = y; y = tmp; }  這裏只能交換兩個整