Подтвердить что ты не робот

Включить файл .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

Однако это ничего не меняет. Сообщения об ошибках остаются неизменными. Я пытался найти некоторую информацию в Интернете, однако это не получилось.

4b9b3361

Ответ 1

Вы создаете шаблон класса, который имеет важное предостережение о том, что все определения переменных должны быть помещены в заголовочный файл, чтобы они были доступны для всех единиц перевода во время компиляции.

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

Переместите все определения методов из файла .cpp и в файл .h, и все должно быть в порядке (при условии, что на самом деле вы предоставили определение для конструктора по умолчанию!).

В качестве альтернативы вы можете обойти это, явно сообщив компилятору о создании соответствующего класса шаблонов, используя что-то вроде template class LinkedList<int>, но это действительно не обязательно в таком простом случае. Основным преимуществом этого, включая все определения в файле заголовка, является то, что он потенциально уменьшает раздувание кода и ускоряет компиляцию. Но это может и не понадобиться, поскольку компиляторы стали намного умнее при применении соответствующих оптимизаций.

Ответ 2

Вы разделили свой класс LinkedList и поместили объявление в заголовок и defintion в исходном файле. Это не работает для шаблона. Оба должны быть в заголовке.

Ответ 3

Так как LinkedList является шаблоном класса, определения его функций-членов должны идти в заголовке.

(Они не обязательно должны быть, строго говоря, но это самый простой способ обойти сложности создания шаблонов, не переходя полностью вне трасс с соглашениями о включении.)

О, и вам все равно понадобится второй подход к сборке; вам необходимо связать все файлы .cpp или использовать переключатель -c для компиляции по одному, а затем связать результаты позже.

Ответ 4

Класс шаблона похож на определение правила, с помощью которого можно построить фактический класс. Фактические классы создаются (создаются экземплярами) компилятором везде, где есть экземпляр класса шаблона. По этой причине весь код класса шаблона должен быть видимым компилятору в этой точке и поэтому вам нужно написать все функции и методы шаблона в файлах заголовков - поскольку вы включаете только заголовки в файлы cpp, видны только заголовки к компилятору в этот момент. Вы не включаете файлы cpp в другие файлы cpp, и вы никогда не должны этого делать.

Исправьте меня, если мое понимание неверно.

Р. С. С++ 11 решает эту проблему?

Ответ 5

есть ссылка undefined на ссылку LinkedList:: LinkedList() '

Вы проверили, имеет ли ваш класс LinkedList конструктор?