Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/21: Рейтинг темы: голосов - 21, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 8
1

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

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

Author24 — интернет-сервис помощи студентам
Написал минимальный код, генерирующий такую ошибку. Сборщик ругается, что конструктор 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
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 return 0; } void...

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

6
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
19.09.2014, 23:33 2
Mr Snail, шаблоны вроде как нужно полностью определять в заголовке, т.е. .h я имею виду
0
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
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
19.09.2014, 23:49 4
Mr Snail, потому что отдельный маин.срр должен видеть то место, где определяется шаблон, во втором случае он его видит как нельзя лучше, в первом есть 2 единицы трансляции (или как-то так, могу путать) маин + .h и .h + .cpp шаблона. соответственно маин и не видит
можно добавить .cpp в инклуды, должно тоже прокатить
0
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 8
19.09.2014, 23:54  [ТС] 5
Но почему в случае нешаблонного класса main.cpp "видит" Obj.cpp ?
0
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
20.09.2014, 00:02 6
Mr Snail, сумбурно наверно пояснил. Может так будет лучше:
Когда вы создаете какой-то класс (не шаблонный), компилятор из .cpp склепает СРАЗУ объектный файл, а мейн лишь будет вызывать оттуда функции, которые прописаны в .h И не важно, как они там реализованы, мейн это не волнует.
Но когда вы пытаетесь написать шаблонный класс, компилятор НИЧЕГО не создаст просто так, он будет создавать по мере необходимости. И вот увидев, что надо создать по шаблону объект для int, компилятор ищет соответствующий шаблон, по которому он должен создать объект. НО он найдет лишь заголовок из .h Про Obj1.cpp он вообще понятия не имеет, т.к. его нет в инклудах майна.

Добавлено через 2 минуты
PS: только начинаю учиться, могут быть неточности в терминологии. Но постарался отразить суть.
1
18898 / 9856 / 2410
Регистрация: 30.01.2014
Сообщений: 17,299
20.09.2014, 00:13 7
Цитата Сообщение от Mr Snail Посмотреть сообщение
Но почему в случае нешаблонного класса main.cpp "видит" Obj.cpp ?
Компиляция в С++ раздельная (каждый файл (обычно cpp) компилируется независимо).
Линкер связывает (как ты сказал "видит") имена сущностей между разными модулями.
Шаблон - это, считай, образец для кода. Кодом он становится только при подстановке аргументов - инстанцировании. Чтобы была возможность сгенерировать по образцу (шаблону) код, нужно чтобы весь он был доступен в месте генерации (еще раз вспоминаем, что компиляция в С++ раздельная). Когда ты разнес его по разным модулям, то ты лишил main полной информации о шаблоне. Отсюда и ошибка.
Вот связанная с твоей тема.
1
20.09.2014, 00:13
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.09.2014, 00:13
Помогаю со студенческими работами здесь

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

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

Ошибка LNK2005 в многофайловом проекте
Появилась такая проблема ,выдает ошибку LNK2005 при компиляции программы,вроде сделано все...

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


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru