2010-09-06 41 views
2

根據 Storing C++ template function definitions in a .CPP file能模板摘要(純虛擬)類的定義放在源文件C++

很容易seprate界面和模板類的實現,

.h文件中

template<typename T> 
class foo 
{ 
    public: 
    foo(); 
    ~foo(); 
    void do(const T& t); 
}; 

.cpp文件

template <typename T> 
void foo::foo() 
{ 
    // initiate 
} 

//destructor 

template <typename T> 
void foo::do(const T& t) 
{ 
    // Do something with t 
} 

void foo<int> fi; 
void foo<std::string> fs; 

竅門是通過在.cpp文件末尾創建實例來專門化模板類。

但是,如果這是一個純虛模板類

.h文件中

template<typename T> 
class foo 
{ 
    public: 
    foo(); 
    ~foo(); 
    virtual void do(const T& t) = 0; 
}; 

,我們從這個派生的具體類:

template<typename T> 
class foobar : public foo<T> 
{ 
    public: 
    void do(const T& t); 
}; 

源文件此課程看起來像

cpp文件

template <typename T> 
void foobar::do(const T& t) 
{ 
    // Do something with t 
} 

void foobar<int> fi; 
void foobar<std::string> fs; 

和foo的源文件看起來除了灌頂同一被除去(因爲現在ofcourse foo是一個抽象類)。

但現在有一個鏈接器錯誤; foo<int>()foobar<int>的構造函數中未解決。這通過將foo的構造函數和析構函數移回源文件的頭文件來解決。

所以我的問題是我們如何創建抽象模板基類,並保持隱藏在源文件中的模板類的定義?

+0

非抽象'foo '鏈接? – 2010-09-06 09:44:01

回答

1

你可以顯式實例化一個類型而不需要實例化一個變量。此外,您現有的代碼被嚴重竊取,甚至無法編譯。

template<typename T> 
class foo 
{ 
    public: 
    foo(); 
    ~foo(); 
    void something(const T& t); 
}; 

template <typename T> 
foo<T>::foo() 
{ 
    // initiate 
} 

//destructor 

template <typename T> 
void foo<T>::something(const T& t) 
{ 
    // Do something with t 
} 
template<typename T> 
foo<T>::~foo() { 
} 

template class foo<int>; 

這將實例化foo作爲int類型,但不需要混淆變量。

+0

謝謝,這當然是一個更易於管理的方法。 – aukm 2010-09-06 10:10:47

1

您需要實例中Foo.cpp中的構造以及:

template void foo<int>::foo(const int&); 

您也將這樣做對foobar它是可用的。

+0

謝謝你的工作,所以這意味着抽象類的所有成員都需要在.cpp文件中針對所有不同的專業化開始。多麼痛苦!你知道一個更優雅的方法來分離模板類的接口和實現嗎? – aukm 2010-09-06 09:59:18

+1

@aukm:是的,看我的答案。 – 2010-09-06 10:00:04

2

,我建議你爲這個創建其他類:

#include <string> 

template<typename T_Foo> 
struct FooCompilation 
{ 
    void operator()() 
    { 
    T_Foo foo; 
    typedef typename T_Foo::T T; 
    T t; 
    foo.do(t); 
    } 
}; 

template FooCompilation<Foo<int> >; 
template FooCompilation<Foo<std::string> >; 

這應該工作,因爲編譯器會嘗試實例化所需的所有代碼的內部操作者()的代碼工作。