Ошибка связи при использовании исходных файлов вне корневого каталога проекта (файлы, включенные в пути поиска) (Visual C ++) - PullRequest
2 голосов
/ 07 июня 2011

Я программировал структуру шаблона, и после того, как он заработал, я решил использовать его в каком-то другом проекте.Шаблон состоит из двух файлов.ListOctree.cpp и ListOctree.h.Хотя они самостоятельно компилируются и работают (я могу запустить самопроверку структуры).

При использовании их в другом проекте оба ListOctree.cpp / .h находятся в каталоге ./Util, нов то время как Visual Studio, похоже, находит файл .h (я могу использовать объявления .h в любом месте проекта), похоже, что он не может найти исходный файл .cpp, где объявлен весь код, объявленный в .h.

Файлы являются частью проекта.Дерево ists выглядит примерно так:

program.cpp <-- includes "Util/ListOctree.h"
/Util
    ListOctree.cpp
    ListOctree.h

Все классы и функции из ListOctree принадлежат пространству имен Util.

Ошибка, которую выдает Visual C ++: error LNK2019: símbolo externo "public: __thiscall Util :: ListOctree :: ListOctree (int) "(...) sin resolver ...

Aprox.на английском: ошибка LNK2019: внешний символ «public: __thiscall Util :: ListOctree :: ListOctree (int)» (...) не разрешен ...

При перестройке решения Util / ListOctree.cppскомпилировал сгенерированный файл .obj, но, похоже, он не может связать его вместе

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

Приложение:где и как я использую файл .h

#include "Util/ListOctree.h"
//...
void main (){
//...
    ListOctree<int>* a = new ListOctree<int>(8);
//...
}

Приложение: Util / ListOctree.h

#ifndef __UTIL_LISTOCTREE
#define __UTIL_LISTOCTREE

//Conditional compilation flags

#undef _SELFTEST
#undef _DEBUG_LISTOCTREE

//Conditional compilation options
#ifdef _DEBUG_LISTOCTREE
 #undef  _DEALLOCATE_LISTS
 #define _SELFTEST
#endif

#ifdef _SELFTEST
 #include <iostream>
#endif

#ifdef _SELFTEST
 #include<assert.h>
#endif

#ifdef _DEBUG_LISTOCTREE
 #include <iostream>
#endif
/////////////////////////////////

#include <deque>
#include <list>
#include <iterator>
#include <math.h>
#include <exception>

//Remind me to never do this again. (xYz,XYz,XYZ,xYZ,xyz,Xyz,XyZ,xyZ,)
//A CAPS character means positive in the axis while a
//Lowercase character means negative
//FIXME Never used I think.
#define _xyz sons[0]
#define _xyZ sons[1]
#define _xYz sons[2]
#define _xYZ sons[3]
#define _Xyz sons[4]
#define _XyZ sons[5]
#define _XYz sons[6]
#define _XYZ sons[7]

namespace Util{
/**
 * @brief The node class
 *
 * Each node stores up to 8 sons, a parent pointer and, if it
 * is a Leaf node, a list of contents.
 */
template <typename T> class Node{
    //Attributes
public:
    ///An array with all the sons
    Node<T>* sons[8];
    ///A parent pointer
    Node<T>* parent;

    //The node contents (if any)
    std::list<T>* c;

    //Methods
public:
    /// Deallocates itself AND all of it's sons
    ~Node();
    /// Creates an empty node
    Node();
    /// Creates a node with its eight sons and a parent reference from an 9 pointer array
    Node(Node<T>** nodes);
    ///Returns the node contents
    std::list<T>* getContents(){return c;};
    ///Pushes an item into the node
    void pushItem(T item);
    ///Removes an item from the node
    void eraseItem(T item){c->erase(item);};
    ///Clears the node contents
    void clearNode(){c->clear();};
};

/**
 * @brief Container for @see Node classes
 *
 * This class allows a more convenient way of working with Octrees
 */
template <typename T> class ListOctree {
    //Attributes
private:
    int width;
    Node<T>* root;

    //Methods
public:
    ListOctree(int width);
    ~ListOctree();
    void pushItemAt(T item, int x, int y, int z);
    void eraseItemAt(T item, int x, int y, int z);
    void clearItemsAt(int x, int y, int z);
    std::list<T>* getItems();
    std::list<T>* operator() (int x, int y, int z){return(getItemsAt(x,y,z));};
    std::list<T>* getItemsAt(int x, int y, int z);
private:
    char nextNode(int x, int y, int z, int* cx, int* cy, int* cz, int width, Node<T>* n, bool createNew) throw(...);
    void _pushItemAt(T item, int x, int y, int z, int cx, int cy, int cz, int width, Node<T>* n);
    void _eraseItemAt(T item, int x, int y, int z, int cx, int cy, int cz, int width, Node<T>* n);
    void _clearItemsAt(int x, int y, int z, int cx, int cy, int cz, int width, Node<T>* n);
    std::list<T>* _getItemsAt(int x, int y, int z, int cx, int cy, int cz, int width, Node<T>* n);
    void prune(Node<T>* n);
    void addItemsToList(std::list<T>* lst, Node<T>* n);
};

/**
 * @brief Exception used internally
 * 
 * FIXME, never used, can't be used for some reason
 */
class ListOctreeException : public std::exception{
private:
    std::string msg;

public:
    ListOctreeException(){msg="ListOctreeException";};
    ListOctreeException(std::string s){msg=s;};
    const char* what(){return(msg.c_str());};
};
};//namespace
#endif

Ответы [ 2 ]

0 голосов
/ 07 июня 2011

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

Ключевое слово export, которое предполагалось использовать в случае, когда они разделены, но лишь немногие компиляторы реализовали его, и теперь оно удалено в c ++ 0x.

0 голосов
/ 07 июня 2011

Вы добавили ссылку между проектами в своем решении?(Visual Studio 2010)

Щелкните правой кнопкой мыши Project-> References

Или вы добавили зависимость проекта?(Visual Studio 2008)

...