Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
Mr Snail
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 8
#1

Ошибка lnk2019 для шаблонов в многофайловом приложении

19.09.2014, 23:30. Просмотров 1037. Ответов 6
Метки нет (Все метки)

Написал минимальный код, генерирующий такую ошибку. Сборщик ругается, что конструктор Obj1 не определен. Разве все cpp файлы, включенные в проект, не компилируются автоматически? Если сделать класс не шаблонным, ошибки не будет. Как избавиться от этой ошибки не объединяя эти файлы?
файл Obj1.h:
C++
1
2
3
4
5
template<typename T>
class Obj1{
public:
    Obj1();
};
файл Obj1.cpp:
C++
1
2
3
4
#include "Obj1.h"
 
template <typename T>
Obj1<T>::Obj1(){}
файл main.cpp:
C++
1
2
3
4
5
#include "Obj1.h"
 
void main(){
    Obj1<int> A;
}
Ошибка:
1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall Obj1<int>::Obj1<int>(void)" (??0?$Obj1@H@@QAE@XZ) в функции _main
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2014, 23:30
Ответы с готовыми решениями:

Ошибка LNK2019 в многофайловом проекте
Смысл: Мне нужно создать абстрактный класс контейнер, на его основе конкретные...

Ошибка 2019 с линковщиком в многофайловом приложении
не могу понять в чем тут проблема. выдает ошибки: 1&gt;main.obj : error LNK2019:...

Баг VS или как? Функция в многофайловом приложении
#include &quot;function.h&quot; int main(){ LoadFileToStack(); cout &lt;&lt; endl; st...

Программа из учебника Прата. Структуры в многофайловом приложении. Исправить недочеты в коде
Посмотрите, пожалуйста, что где исправить. int fill()-для заполнения массива...

Использование string в многофайловом приложении. Необходимость подключения библиотек и пространства имён
Здравствуйте. Есть заголовочный и cpp файлы. В заголовочном пишу#ifndef MODEL_H...

6
КОП
472 / 365 / 117
Регистрация: 15.08.2010
Сообщений: 997
Завершенные тесты: 1
19.09.2014, 23:33 #2
Mr Snail, шаблоны вроде как нужно полностью определять в заголовке, т.е. .h я имею виду
0
Mr Snail
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 8
19.09.2014, 23:43  [ТС] #3
Если удалить main.cpp, а файл Obj1.cpp написать как:
C++
1
2
3
4
5
6
7
8
#include "Obj1.h"
 
template <typename T>
Obj1<T>::Obj1(){}
 
void main(){
    Obj1<int> A;
}
то ошибка пропадает, хотя определение не в заголовке, так что проблема не в этом.
0
КОП
472 / 365 / 117
Регистрация: 15.08.2010
Сообщений: 997
Завершенные тесты: 1
19.09.2014, 23:49 #4
Mr Snail, потому что отдельный маин.срр должен видеть то место, где определяется шаблон, во втором случае он его видит как нельзя лучше, в первом есть 2 единицы трансляции (или как-то так, могу путать) маин + .h и .h + .cpp шаблона. соответственно маин и не видит
можно добавить .cpp в инклуды, должно тоже прокатить
0
Mr Snail
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 8
19.09.2014, 23:54  [ТС] #5
Но почему в случае нешаблонного класса main.cpp "видит" Obj.cpp ?
0
КОП
472 / 365 / 117
Регистрация: 15.08.2010
Сообщений: 997
Завершенные тесты: 1
20.09.2014, 00:02 #6
Mr Snail, сумбурно наверно пояснил. Может так будет лучше:
Когда вы создаете какой-то класс (не шаблонный), компилятор из .cpp склепает СРАЗУ объектный файл, а мейн лишь будет вызывать оттуда функции, которые прописаны в .h И не важно, как они там реализованы, мейн это не волнует.
Но когда вы пытаетесь написать шаблонный класс, компилятор НИЧЕГО не создаст просто так, он будет создавать по мере необходимости. И вот увидев, что надо создать по шаблону объект для int, компилятор ищет соответствующий шаблон, по которому он должен создать объект. НО он найдет лишь заголовок из .h Про Obj1.cpp он вообще понятия не имеет, т.к. его нет в инклудах майна.

Добавлено через 2 минуты
PS: только начинаю учиться, могут быть неточности в терминологии. Но постарался отразить суть.
1
DrOffset
7951 / 4618 / 1124
Регистрация: 30.01.2014
Сообщений: 7,516
20.09.2014, 00:13 #7
Цитата Сообщение от Mr Snail Посмотреть сообщение
Но почему в случае нешаблонного класса main.cpp "видит" Obj.cpp ?
Компиляция в С++ раздельная (каждый файл (обычно cpp) компилируется независимо).
Линкер связывает (как ты сказал "видит") имена сущностей между разными модулями.
Шаблон - это, считай, образец для кода. Кодом он становится только при подстановке аргументов - инстанцировании. Чтобы была возможность сгенерировать по образцу (шаблону) код, нужно чтобы весь он был доступен в месте генерации (еще раз вспоминаем, что компиляция в С++ раздельная). Когда ты разнес его по разным модулям, то ты лишил main полной информации о шаблоне. Отсюда и ошибка.
Вот связанная с твоей тема.
1
20.09.2014, 00:13
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.09.2014, 00:13

Ошибка в приложении: "error LNK2019: ссылка на неразрешенный внешний символ"
Создал консольное приложение и в него добавил код: #include &quot;afxwin.h&quot; // MFC...

Ошибка линковки в многофайловом проекте
что за на??? в проекте 3 модуля: main.cpp, test.cpp, test.h, в main.cpp и...

Ошибка при работе с шаблонами в многофайловом проекте
Цель проста - пишу класс очереди, используя шаблоны. Возниает следующая ошибка:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru