2012-02-10 75 views
6

我有一個模板類,它從一個接口類繼承,因此有虛函數未定義的參考`虛函數表的模板

//abstract.h 
class Abstract { 
virtual void abc(); 
Abstract(); 
} 
//Abstract.cpp 
Abstract::Abstract() 
{ //do some init} 

//concrete.h 
class Impl { 
public: 
    void abcImpl(); 
}; 

template<typename T> 
class Concrete : public Abstract, public T { 
virtual void abc(); 
}; 
template<typename T> 
Concrete<t>::abc() { static_cast<T>(*this).abcImpl(); } 

//concrete.cpp 
void Impl::abc() { std::cout << "abc"; } 

這裏

//foo.cpp 
Concrete<Impl> *var1 = new Concrete<Impl>(); 

用於在鏈接的時候,我得到一個錯誤 未定義對`vtable for Abstract'的引用

過去,這個錯誤表明編譯器找不到放置vtable的地方,因爲wa沒有與該類關聯的cpp文件。換句話說,它將vtable放在第一個找到任何成員函數的第一個非虛擬定義的地方。 但這是令人費解的,因爲。 1.我不知道它爲什麼抱怨抽象 - 抽象其實有一個cpp 2.也許錯誤信息msg實際上意味着具體?但混凝土不能放在cpp文件中,因爲它的模板化。 那麼在處理一個也具有虛函數的模板類時,通常如何解決這個問題呢?

+4

這是實際的碼? 'Concrete'不是從'Abstract'派生的。注意'Abstract :: abc()'不是一個純虛函數,因此必須定義。 – hmjd 2012-02-10 21:50:47

+0

[Undefined symbols「vtable for ...」和「typeinfo for ...」可能重複?](http://stackoverflow.com/questions/1693634/undefined-symbols-vtable-for-and-typeinfo-for ) – 2012-02-10 23:48:21

回答

3

問題可能是由於abc()方法未聲明爲純虛擬方法。例如,GCC將使用abc()作爲vtable佈局的關鍵方法,因爲它是該類中首次聲明的非內聯非純虛方法(詳細信息:http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html)。如果聲明abs()純虛擬,它應該將vtable放在Abstract.cpp中定義構造函數的地方。