2013-03-21 2 views
1

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

g++ -g -Wall DynamicSequenceVector.cpp DynamicSequenceVector.h main.cpp 

Я получаю следующий вывод консоли

/tmp/cc6P5VZK.o: In function `main': 
main.cpp:(.text+0x1a): undefined reference to `DynamicNode::DynamicSequenceVector<int>::DynamicSequenceVector(int)' 
main.cpp:(.text+0x3a): undefined reference to `DynamicNode::DynamicSequenceVector<int>::~DynamicSequenceVector()' 
main.cpp:(.text+0x4f): undefined reference to `DynamicNode::DynamicSequenceVector<int>::~DynamicSequenceVector()' 
collect2: error: ld returned 1 exit status 

У меня есть чувство, что это проблема с тем, как я импортировать файлы в главном. cpp, потому что, если я переведу основную функцию в файл DyanmicSequenceVector.cpp, она компилируется отлично. Кроме того, я получаю эти ошибки при создании нового объекта с параметром.

DynamicSequenceVector.h

#ifndef __DYNAMIC_VECTOR 
#define __DYNAMIC_VECTOR 

namespace DynamicNode { 

template <class Type> 
class DynamicSequenceVector { 
    private: 
     struct dynamicNode { 
      dynamicNode *previousLink; 
      dynamicNode *nextLink; 
      Type data; 
      int position; 
     }; 

     int nodeCount; 
     int currentPosition; 
     dynamicNode *headNode; 
     dynamicNode *tailNode; 
     dynamicNode *currentNode; 
     dynamicNode *tempNode; 

    public: 
     DynamicSequenceVector(); 
     DynamicSequenceVector(Type data); 
     ~DynamicSequenceVector(); 
     void appendNode(Type nodeData); 
     void accessData(int startingPosition, int endingPosition); 
}; 

} 
#endif 

DynamicSequenceVector.cpp

#include <iostream> 
#include "DynamicSequenceVector.h" 

using namespace std; 
using namespace DynamicNode; 

template <typename Type> 
DynamicSequenceVector<Type>::DynamicSequenceVector() { 
    nodeCount  = 0; 
    currentPosition = NULL; 
    headNode  = NULL; 
    tailNode  = NULL; 
    currentNode  = NULL; 
} 

template <typename Type> 
DynamicSequenceVector<Type>::DynamicSequenceVector(Type nodeData) { 
    nodeCount    = 1; 
    currentPosition  = 0; 
    headNode    = new dynamicNode; 
    headNode->previousLink = NULL; 
    headNode->nextLink  = NULL; 
    headNode->data   = nodeData; 
    headNode->position  = 0; 
    currentNode   = 
} 

template <typename Type> 
DynamicSequenceVector<Type>::~DynamicSequenceVector() { 
    while(nodeCount != 0) { 
     tempNode = tailNode->previousLink; 
     delete tailNode; 
     tailNode = tempNode; 
    } 
    return; 
} 

template <typename Type> 
void DynamicSequenceVector<Type>::appendNode(Type nodeData) { 
    if (currentPosition == 0) { 
     headNode    = new dynamicNode; 
     headNode->data   = nodeData; 
     headNode->position  = 0; 
     headNode->previousLink = NULL; 
     headNode->nextLink  = NULL; 
    } else { 
     tempNode    = new dynamicNode; 
     tempNode->data   = nodeData; 
     tempNode->previousLink = tailNode; 
     tempNode->position  = nodeCount + 1; 
     tailNode->nextLink  = tempNode; 
     tailNode    = tempNode; 
    } 

    nodeCount++; 
} 

template <typename Type> 
void DynamicSequenceVector<Type>::accessData(int startingPosition, 
     int endingPosition) { 
    cout << "Data accessed"; 
    return 0; 
} 

main.cpp

#include <iostream> 
#include "DynamicSequenceVector.h" 

//using namespace std; 
using namespace DynamicNode; 

int main() { 
    DynamicSequenceVector<int> test(); 
    DynamicSequenceVector<int> testingVector(5); // gives an error 
    //test = new DynamicSequenceVector<char>::DynamicSequenceVector(); 

    std::cout << "Hello world!\n"; 
} 
+1

переместить определение функций шаблона заголовка. –

+2

Вы не можете поместить определение функций-членов шаблона класса в файлы '.cpp'. Переместите их в заголовок –

+0

@AndyProwl Ну, если вы вручную создаете шаблон, тогда да, вы можете ... но это больше работает. – cdhowie

ответ

3

Реализация членов шаблона должен быть в заголовке, а не в отдельном .cpp-файл.

При компиляции main.cpp компилятору требуется реализация должна быть видимой, чтобы создать экземпляр DynamicSequenceVector<int>, и они недоступны. Поэтому компилятор предполагает, что экземпляр шаблона доступен в другом модуле компиляции, но это не так, и поэтому компоновщик терпит неудачу.

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


в качестве альтернативы, вы можете добавить это в нижней части DynamicSequenceVector.cpp:.

template class DynamicSequenceVector<int>; 

Это будет указывать компилятору создать экземпляр этой версии класс шаблона и сделать его доступным и экспортированным из этого модуля компиляции. Затем, когда компоновщик переходит к разрешению символов в модуле компиляции main, он сможет их найти.

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

+0

Если я поставлю оператор include для файла cpp в основной файл, кажется Скомпилировать. Благодарю. – user1876508

+1

@ user1876508 Да, но включая исходный файл *** неправильно ***. Не делай этого. Поместите реализацию в заголовок, где он принадлежит, и выбросьте исходный файл. Вам это не нужно. – cdhowie

+1

@ user1876508, по крайней мере, переименуйте файл cpp в 'DynamicSequenceVectorInlines.h' и включите его в конец' DynamicSequenceVector.h' –

1

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

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