0

Рассмотрим следующий код. A - абстрактный, общий класс; B оба реализует и специализирует его. Этот код кажется мне тривиально правильным, но по какой-то причине я заканчиваю странные ошибки компоновщика.Шаблон класса с виртуальным членом: ошибка компоновщика

template<typename T> 
class A { 
    public: 
     virtual void f(); 
}; 

class B : public A<int> { 
    public: 
     void f() {}; 
}; 

int main(int argc, char** argv) { 
    auto b = new B(); 
    return 0; 
} 

выход GCC: выход

/tmp/ccXG2Z8A.o:(.rodata._ZTV1AIiE[_ZTV1AIiE]+0x10): undefined reference to `A<int>::foo()' 
collect2: error: ld returned 1 exit status 

лязг:

/tmp/l2-2a09ab.o: In function `main': 
l2.cpp:(.text+0x35): undefined reference to `operator new(unsigned long)' 
/tmp/l2-2a09ab.o:(.rodata._ZTI1AIiE[_ZTI1AIiE]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info' 
/tmp/l2-2a09ab.o:(.rodata._ZTI1B[_ZTI1B]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info' 
/tmp/l2-2a09ab.o:(.rodata._ZTV1AIiE[_ZTV1AIiE]+0x10): undefined reference to `A<int>::foo()' 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
+1

Прежде всего, A не является абстрактным классом. Вы должны сделать: virtual void foo() = 0; чтобы сделать его чистой виртуальной функцией – Asesh

+0

Так оно и было, спасибо. Если вы представите это в качестве ответа, я соглашусь с ним. –

+1

вы должны реализовать 'A :: f()' или сделать его чистым виртуальным. Если отсутствует виртуальный метод, компоновщик не может построить таблицу виртуальных методов 'A'. Поэтому появляется это сообщение. – Franck

ответ

1

С GCC выхода, я буду считать, что функция называется foo вместо просто f.

Проблема в том, что класс A не является абстрактным, потому что вы не объявили его метод как таковой. Вы бы сделать так, таким образом:

virtual void foo() = 0; 

Но вы забыли = 0, так что линкер не знает, что метод является абстрактным, и поэтому ищет тело функции, которая не существует.

1

А не является абстрактным классом. Вы должны сделать:

virtual void f() = 0; 

сделать это чисто виртуальная функция