2012-01-12 2 views
14

Можно создать дубликат:
Why can templates only be implemented in the header file?Включить .cpp-файл?

Я пытался вокруг с C++ в последнее время. На данный момент я пытаюсь запрограммировать что-то, что я уверен, что когда-либо сделал это хотя бы один раз: простой класс 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 

Я получаю сказал, что есть неопределенная ссылка на «LinkedList :: LinkedList()». Так я думал, что это они связаны неправильно, поскольку есть более чем один .cpp файл, поэтому я попытался это так:

g++ -c -Wall -O2 ..\src\test.cpp 
g++ -c -Wall -O2 ..\src\linkedlist.cpp 
g++ -s test.o linkedlist.o 

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

+3

Хорошо сделано для формулировки этого полностью и согласованно. :) Редкий для новичков, в настоящее время :( –

+0

Поскольку «LinkedList» является классом шаблона, пользователям этого класса необходимо полное определение всех методов. Один из способов сделать это - иметь все методы inline в классе, а другой - поместить методы в отдельный файл и включить их в заголовочный файл. –

+0

@Mike: Трудно назвать это «дубликатом» как таковым. Здесь все становится нечетким - вопрос совершенно другой, даже если мы надеваем Не нужно снова покрывать ту же землю. :) –

ответ

5

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

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

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

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

+2

Ключевое слово 'export' больше не существует, и оно было только смутно поддержано ранее. –

2

Вы разделили свой класс LinkedList и поместили объявление в заголовок и исправление в исходном файле. This does not work for a template. Оба должны быть в заголовке.

+0

Он действительно сказал: «Тогда есть .cpp-файл с именем linkedlist.cpp, который содержит весь фактический код класса LinkerList.« –

+0

То, что я получаю только за вопросы по скиммированию - исправлено. –

+0

Вы прощены за такие вопросы:) –

1

С LinkedList является класс шаблон, the definitions of its member functions ought to go in a header.

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

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

0

есть неопределенная ссылка на 'LinkedList :: LinkedList()'

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

1

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

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

P. S. Обсуждает ли C++ 11 эту проблему?

+1

P.S. Нет. Нет, нет. C++ 03 попытался и не смог, поэтому C++ 11 отказался и фактически удалил попытку. –

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