2015-12-02 97 views
3

我想爲模板類分開.h和.cpp。 下面是我在做什麼:C++模板頭cpp分離,包含* .cpp到* .h的解決方案不再工作

  1. 我寫了直接的.h和.cpp就像沒有模板。因此它創建了一個例外,如Link 2019 Template exception
  2. 有一些解決方案來處理此How to define template class header and implement it in another cpp。我選擇溶液3
  3. 根據我加入包括內部只是頭#ENDIF之前*的.cpp該溶液中。(靜止*的.cpp包括* .h)中(以下代碼表示這個步驟)它給

    模板已經被定義錯誤。

  4. 根據研究的擺脫這種錯誤的方式(循環依賴)刪除的#include *從*的.cpp .H但這次

    面目全非模板聲明/定義錯誤

發生。我的問題是如果我將* .cpp包含到* .h文件。我們如何才能按預期構建項目?或者這個解決方案是絕對的?

// TestTemp.h 
#ifndef _TESTTEMP_H_ 
#define _TESTTEMP_H_ 
template<class T> 
class TestTemp 
{ 
public: 
    TestTemp(); 
    void SetValue(T obj_i); 
    T Getalue(); 
private: 
    T m_Obj; 
}; 
#include "TestTemp.cpp" 

#endif 

// TestTemp.cpp 
#include "TestTemp.h" 
template <class T> 
TestTemp<T>::TestTemp() 
{ 
} 
template <class T> 
void TestTemp<T>::SetValue(T obj_i) 
{ 
} 

template <class T> 
T TestTemp<T>::Getalue() 
{ 
    return m_Obj; 
} 

#include "TestTemp.h" 

int main() 
{ 
    TestTemp<int> a; 
    a.Getalue(); 
    return 0; 
} 
+2

您是否確定不要在構建中包含cpp文件?它不應該嘗試編譯它。 – NathanOliver

+0

@NathanOliver我有3個文件顯示在上面,我正在使用Visual Studio爲了建立它們與這些狀態。 – Yunus

+1

這是一篇很糟糕的文章,忘記了你每讀一遍。你不應該這樣做。此代碼(和文章)還存在其他問題,例如使用無效標識符(不能在標識符開頭使用下劃線後跟大寫字母)。 –

回答

3

不同於普通的類的成員函數,模板類的成員函數不能單獨編譯並鏈接到可執行文件。編譯器在使用模板時必須對模板的成員可見。那就是所有那些荒謬的東西都包含在那篇可怕的文章中。

要做到這一點,最簡單的方法是直接把定義爲模板定義:

#ifndef TEST_H 
#define TEST_H 

template <class Ty> 
class test { 
public: 
    void f() { /* whatever */ } 
}; 
#endif 

其缺點是大課變得不可讀(參見JAVA)。因此,下一步是將定義模板之外,但讓他們在標題:

#ifndef TEST_H 
#define TEST_H 

template <class Ty> 
class test { 
public: 
    void f(); 
}; 

template <class Ty> 
void test<Ty>::f() { /* whatever */ } 

#endif 

很多人都覺得這仍然過於雜亂,並希望把這些定義成一個單獨的文件。這沒關係,太多,但你必須確保只要原來的報頭使用了單獨的文件被包括:

#ifndef TEST_H 
#define TEST_H 

template <class Ty> 
class test { 
public: 
    void f(); 
}; 

#include "test.imp" 

#endif 

這是文件「test.imp」:

#ifndef TEST_IMP 
#define TEST_IMP 

template <class Ty> 
void test<Ty>::f() { /* whatever */ } 

#endif 

注意「test.imp」實際上是一個頭文件,因此它通過test.h中的#include "test.imp"指令進入代碼。它不能單獨編譯,所以如果而不是被命名爲.cpp擴展名,這最多隻會導致誤導。

+0

感謝您提供非常重要的信息。我測試了它的作品。 – Yunus