2012-02-10 8 views
6

Mam klasy szablon, który dziedziczy z klasy interfejsu i dlatego ma funkcje wirtualnychniezdefiniowana odniesienia do `vtable dla szablonu

//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"; } 

Używany tutaj

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

W czasie łącza, otrzymuję błąd niezdefiniowane odniesienie do `vtable for Abstract '

W przeszłości ten błąd wskazywał, że kompilator nie mógł znaleźć miejsca do umieszczenia vtable ponieważ s Brak pliku cpp powiązanego z tą klasą. Innymi słowy, umieszcza tabelę vtable tam, gdzie najpierw znajduje pierwszą nie-wirtualną definicję dowolnej funkcji składowej. Ale to jest zagadkowe, ponieważ. 1. Nie mam pewności, dlaczego narzeka na streszczenie - Streszczenie rzeczywiście ma cpp 2. Być może błąd msg faktycznie oznacza Beton? Ale Beton nie może znajdować się w pliku cpp, ponieważ jest zmieniony w templat. Jak rozwiązać problem z klasą szablonów, która ma również funkcje wirtualne?

+4

Czy to jest rzeczywisty kod? 'Concrete' nie pochodzi od' Abstract'. Uwaga 'Streszczenie :: abc()' nie jest czystą funkcją 'wirtualną' i dlatego musi być zdefiniowane. – hmjd

+0

możliwy duplikat [niezdefiniowanych symboli "vtable for ..." i "typeinfo for ..."?] (Http://stackoverflow.com/questions/1693634/undefined-symbols-vtable-for-and-typeinfo-for) –

Odpowiedz

3

Problem może wynikać z metody abc(), która nie została zadeklarowana jako czysta wirtualna. Na przykład GCC użyje abc() jako metody kluczowej do umieszczenia vtable, ponieważ jest pierwszą nieinnowacyjną, nie czystą metodą wirtualną zadeklarowaną w klasie (szczegóły: http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html). Jeśli zadeklarujesz abs() czystą wirtualną, to powinieneś umieścić vtable w Abstract.cpp, gdzie zdefiniowany jest konstruktor.