Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Visual C++ проблемма с линкером (http://forum.oszone.net/showthread.php?t=207448)

DaRiYs 24-05-2011 02:57 1681477

Visual C++ проблемма с линкером
 
Писал программу, вроде бы все правильно, а вылетают такие ошибки:
error LNK2019: unresolved external symbol "public: __thiscall vector<int>::~vector<int>(void)" (??1?$vector@H@@QAE@XZ) referenced in function _main Lr9_10.obj Lr9_10
error LNK2019: unresolved external symbol "public: void __thiscall vector<int>::push_back(int)" (?push_back@?$vector@H@@QAEXH@Z) referenced in function _main Lr9_10.obj Lr9_10
error LNK2019: unresolved external symbol "public: __thiscall vector<int>::vector<int>(void)" (??0?$vector@H@@QAE@XZ) referenced in function _main Lr9_10.obj Lr9_10

Среда Visual Studio 2008
Вот код программы:


Код:

//main.cpp
#include "stdafx.h"
#include "vector.h"

int main()
{
        vector<int>().push_back(1);
        return 0;
}

//vector.h
#pragma once

template <typename Type>
class vector
{
private:
        int size;
        Type* array;
        static int instanceCounter;
        void newInstance();
public:
        vector();
        vector(int size);
        vector(int size, Type value);
        vector(int size, const Type* pointer);
        vector(const vector& instance);
        int length();
        void push_back(Type value);
        void destroyInstance();
        static int getInstanceCounter();
        vector operator +=(vector instance);
        vector operator +=(Type instance);
        vector operator =(vector instance);
        bool operator ==(vector instance);
        bool operator !=(vector instance);
        Type operator [](int iterator);
        ~vector();
};

template <typename Type> int vector<Type>::instanceCounter=0;

//vector.cpp
#include "stdafx.h"
#include "vector.h"

template <typename Type> vector<Type>::vector()
{
        this.size=0;
        this.array=new Type[size];
        newInstance();
}

template <typename Type> vector<Type>::vector(int size)
{
        this.size=size;
        this.array=new Type[size];
        newInstance();
}

template <typename Type> vector<Type>::vector(int size, Type value)
{
        this.size=size;
        this.array=new Type[size];
        for(int i=0; i<size; i++)
                array[i]=value;
        newInstance();
}

template <typename Type> vector<Type>::vector(int size, const Type* pointer)
{
        this.size=size;
        this.array=new Type[size];
        for(int i=0; i<size; i++)
                array[i]=pointer[i];
        newInstance();
}

template <typename Type> vector<Type>::vector(const vector& instance)
{
        this.size=instance.size;
        this.array=new Type[size];
        for(int i=0; i<size; i++)
                this.array[i]=instance.array[i];
        newInstance();
}

template <typename Type> int vector<Type>::length()
{
        return this.size;
}

template <typename Type> void vector<Type>::push_back(Type value)
{
        this.size++;
        Type* temp=array;
        array=new Type[this.size];
        for(int i=0; i<size-1; i++)
                array[i]=temp[i];
        array[size-1]=value;
}

template <typename Type> void vector<Type>::destroyInstance()
{
        if(instanceCounter>0)
                instanceCounter--;
        delete[] array;
}

template <typename Type> void vector<Type>::newInstance()
{
        instanceCounter++;
}

template <typename Type> static int vector<Type>::getInstanceCounter()
{
        return instanceCounter;
}

template <typename Type> vector<Type> vector<Type>::operator +=(vector instance)
{
        Type* temp=this.array;
        array=new Type[this.size+instance.size];
        for(int i=0; i<this.size+instance.size; i++)
                if(i<this.size)
                        array[i]=temp[i];
                else
                        array[i]=instance.array[i-instance.size+1];
        this.size+=instance.size;
}

template <typename Type> vector<Type> vector<Type>::operator +=(Type instance)
{
        Type* temp=this.array;
        array=new Type[this.size++];
        for(int i=0; i<this.size-1; i++)
                        array[i]=temp[i];
        array[size-1]=instance;
}

template <typename Type> vector<Type> vector<Type>::operator =(vector instance)
{
       
}

template <typename Type> bool vector<Type>::operator ==(vector instance)
{

}

template <typename Type> bool vector<Type>::operator !=(vector instance)
{

}

template <typename Type> Type vector<Type>::operator [](int iterator)
{
        iterator<size ? return this.array[iterator] : return NULL;
}

template <typename Type> vector<Type>::~vector()
{
        destroyInstance();
}

Че делать незнаю((( Помогите, очень срочно надо

El Scorpio 24-05-2011 07:26 1681508

Цитата:

Цитата DaRiYs
#include "stdafx.h"
#include "vector.h" »

Имена стандартных библиотек заключаются не в кавычки, а в <xxx>

Цитата:

Цитата DaRiYs
error LNK2019: unresolved external symbol "public: __thiscall vector<int>::~vector<int>(void)" (??1?$vector@H@@QAE@XZ) referenced in function _main Lr9_10.obj Lr9_10
error LNK2019: unresolved external symbol "public: void __thiscall vector<int>::push_back(int)" (?push_back@?$vector@H@@QAEXH@Z) referenced in function _main Lr9_10.obj Lr9_10
error LNK2019: unresolved external symbol "public: __thiscall vector<int>::vector<int>(void)" (??0?$vector@H@@QAE@XZ) referenced in function _main Lr9_10.obj Lr9_10 »

Это значит, что в "объектных" файлах (формируются в результате компиляции) отсутствует код указанных функций: конструктора, деструктора и метода push_back(int) для класса vector <int>.

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

DaRiYs 24-05-2011 11:49 1681614

Цитата:

Цитата El Scorpio
Имена стандартных библиотек заключаются не в кавычки, а в <xxx> »

vector.h это не стандартная библиотека а написаный мною класс. vector.cpp включен в проэкт.

Цитата:

Цитата El Scorpio
cpp файле (который через include не подключается). »

Насколько я знаю срр-шки никада не инклудятся а добавляются в проэкт.

El Scorpio 25-05-2011 02:38 1682097

Цитата:

Цитата DaRiYs
vector.h это не стандартная библиотека а написаный мною класс. vector.cpp включен в проэкт. »

Обычно такое бывает, когда функция была объявлена, но не определена. Также такая ошибка часто происходит с шаблонами, у которых тело функции расположено в cpp файле (который через include не подключается).

Проблема шаблонов в том, что их машинный код создаётся под каждый экземпляр подставленного типа данных и только в момент использования.
Если разместить исходный код шаблонной функции (метода шаблона класса) в cpp модуля, то этот код в другие модули подключён не будет. Соответственно конкретные реализации указанных функций и методов не скомпилируются.
Перенеси весь код класса vector<T> в vector.h

DaRiYs 25-05-2011 13:29 1682304

Цитата:

Цитата El Scorpio
Перенеси весь код класса vector<T> в vector.h »

Собственно говоря я уже так и сделал. Просто может есть решение как их с срр расположить правильно?

El Scorpio 26-05-2011 01:22 1682708

Повторяю ещё раз - компилируются только те функции, которые используются. А у шаблонов вообще каждая реализация под конкретный класс данных компилируется отдельно по мере использования.
Да, можно разместить код медотодов класса vector<T> в .cpp, а в .h-файле прописать команду на принудительную компиляцию класса vector<int>. Однако в этом случае будет создана только реализация этого класса под один единственный тип данных, а подстановка в шаблон других классов вызовет ту же самую ошибку.

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

DaRiYs 26-05-2011 02:07 1682717

Понял. Спасибо за помощь


Время: 08:20.

Время: 08:20.
© OSzone.net 2001-