2010-11-23 2 views
2

Как я могу получить определение шаблона в отдельные файлы заголовков?Неразрешенные ссылки при использовании наследования

Мой код компилируется, когда он включен в один файл main.cpp.

maip.cpp

#include <windows.h> 
#include <tchar.h> 

template<class T1, class T2> 
class Base { 
public: 
    virtual ~Base() {} 
    virtual T1 f1(); 
    virtual T2 f2(); 
}; 

template<class T1, class T2> 
T1 Base<T1, T2>::f1() {return T1();} 
template<class T1, class T2> 
T2 Base<T1, T2>::f2() {return T2();} 

class Derived : public Base<int, int> { 
public: 
    virtual ~Derived() {} 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int i; 
    Derived d; 
    i = d.f1(); 
    return 0; 
} 

Однако, когда я разбить его я получаю неразрешенных внешних символов:

main.cpp

#include <windows.h> 
#include <tchar.h> 

#include "Base.h" 
#include "Derived.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int i; 
    Derived d; 
    i = d.f1(); 
    return 0; 
} 

Base.h

#pragma once 

template<class T1, class T2> 
class Base { 
public: 
    Base(); 
    virtual ~Base() {} 
    virtual T1 f1(); 
    virtual T2 f2(); 
}; 

template<class T1, class T2> 
T1 Base<T1, T2>::f1() {return T1();} 
template<class T1, class T2> 
T2 Base<T1, T2>::f2() {return T2();} 

Derived.h

#pragma once 

class Derived : public Base<int, int> { 
public: 
    virtual ~Derived() {} 
}; 

Это приводит к:

Ошибка 1 Ошибка LNK2019: неразрешенный внешний символ "общественности: __thiscall Base :: Base (вакуум)" (?? 0? $ Base @ HH @@ QAE @ XZ), ссылка в Функция "public: __thiscall Производные :: Производные (void)" (?? 0Derived @@ QAE @ XZ)

+4

Меньшая точка: `Derived.h` должен включать` Base.h`, поскольку он наследует от `Base`, неудобно запрашивать у клиентов, чтобы они содержали файлы в точном порядке, поэтому каждый заголовок должен быть самодостаточным (т.е. должен компилироваться без каких-либо включенных в него сведений). – 2010-11-23 15:45:10

ответ

5

Вы не представили реализацию для Base. Попробуйте добавить

template<class T1, class T2> 
Base<T1, T2>::Base() { } 

Кроме того, вы можете удалить свою декларацию из своего второго фрагмента кода. (Он также не присутствует в вашем первом примере кода).

Ваш линкер в основном говорит, что Derived::Derived() пытается позвонить Base::Base(), который вы явно заявили, но он не может найти реализацию для него.

Смежные вопросы