Включить файл .cpp?
Возможный дубликат:
Почему шаблоны могут быть реализованы только в файле заголовка?
Недавно я пытался использовать С++.
На данный момент я пытаюсь запрограммировать что-то, что я уверен, что когда-либо сделал это хотя бы один раз: простой класс LinkedList.
Код выполнен, но я как-то не могу его скомпилировать. Я был googling, и кажется, что я неправильно привязываю объектные файлы. Вот как выглядит мой код:
test.cpp
#include "linkedlist.h"
int main()
{
LinkedList<int> list;
// do something
}
linkedlist.h
template <typename T>
class LinkedList
{
// a lot of function and variable definitions
}
Затем есть .cpp файл с именем linkedlist.cpp, который содержит весь фактический код класса LinkerList. При попытке скомпилировать test.cpp с помощью следующей команды:
g++ ..\src\test.cpp
Мне говорят, что есть ссылка undefined на ссылку LinkedList:: LinkedList(). Поэтому я думал, что это связано с неправильным, поскольку там более одного .cpp файла, поэтому я попробовал это следующим образом:
g++ -c -Wall -O2 ..\src\test.cpp
g++ -c -Wall -O2 ..\src\linkedlist.cpp
g++ -s test.o linkedlist.o
Однако это ничего не меняет. Сообщения об ошибках остаются неизменными.
Я пытался найти некоторую информацию в Интернете, однако это не получилось.
Ответы
Ответ 1
Вы создаете шаблон класса, который имеет важное предостережение о том, что все определения переменных должны быть помещены в заголовочный файл, чтобы они были доступны для всех единиц перевода во время компиляции.
Причина заключается в том, как работают шаблоны. Во время компиляции компилятор создает экземпляры классов шаблонов на основе определения шаблона вашего класса. Недостаточно иметь доступ только к объявлениям или подписям: для этого требуется наличие всего определения.
Переместите все определения методов из файла .cpp
и в файл .h
, и все должно быть в порядке (при условии, что на самом деле вы предоставили определение для конструктора по умолчанию!).
В качестве альтернативы вы можете обойти это, явно сообщив компилятору о создании соответствующего класса шаблонов, используя что-то вроде template class LinkedList<int>
, но это действительно не обязательно в таком простом случае. Основным преимуществом этого, включая все определения в файле заголовка, является то, что он потенциально уменьшает раздувание кода и ускоряет компиляцию. Но это может и не понадобиться, поскольку компиляторы стали намного умнее при применении соответствующих оптимизаций.
Ответ 2
Вы разделили свой класс LinkedList
и поместили объявление в заголовок и defintion в исходном файле. Это не работает для шаблона. Оба должны быть в заголовке.
Ответ 3
Так как LinkedList
является шаблоном класса, определения его функций-членов должны идти в заголовке.
(Они не обязательно должны быть, строго говоря, но это самый простой способ обойти сложности создания шаблонов, не переходя полностью вне трасс с соглашениями о включении.)
О, и вам все равно понадобится второй подход к сборке; вам необходимо связать все файлы .cpp
или использовать переключатель -c
для компиляции по одному, а затем связать результаты позже.
Ответ 4
Класс шаблона похож на определение правила, с помощью которого можно построить фактический класс. Фактические классы создаются (создаются экземплярами) компилятором везде, где есть экземпляр класса шаблона. По этой причине весь код класса шаблона должен быть видимым компилятору в этой точке и поэтому вам нужно написать все функции и методы шаблона в файлах заголовков - поскольку вы включаете только заголовки в файлы cpp, видны только заголовки к компилятору в этот момент. Вы не включаете файлы cpp в другие файлы cpp, и вы никогда не должны этого делать.
Исправьте меня, если мое понимание неверно.
Р. С.
С++ 11 решает эту проблему?
Ответ 5
есть ссылка undefined на ссылку LinkedList:: LinkedList() '
Вы проверили, имеет ли ваш класс LinkedList конструктор?