1

リストを作成することにしました(練習上の理由から、車輪の再発明については気にしないでください..)

私はこの LNK2019 ERROR を取得しましたが、そのコード固有のものを信じています。これを修正する方法が見つからないようです (はい、ここで検索しました)

コンパイラがメソッドの定義を認識しないため、問題が発生することがわかりましたが、どうすればよいかわかりません。私は MVS 2010 を使用しているので、リンク引数は自動的に行われます。これが私のコードです。

リスト H:

#ifndef _DLIST
#define _DLIST

#include "Node.h"

template<class DataO>
class Dlist
{
private:
    /* Data Members */
             Node<DataO>* _ndHead;
             Node<DataO>* _ndTail;
    unsigned int   _nLength;

    /* Methods */
    void Delete();

public:
    /* Ctors && Dtors */
    Dlist();
    ~Dlist();

    /* Getters && Setters */
    int Length();

    /* Methods */
    void Add(DataO doData);
    void Clear();
    void RemoveAt(unsigned int nIndex);
    void Remove();
};

#endif

リスト Cpp:

// Dlist.cpp

#include "Dlist.h"

/* ------------------ Dlist Section ------------------ */
/* --- Constracturs && Destractur --- */
template<class DataO> 
Dlist<DataO> :: Dlist()
{
    // Init data
    this->_ndHead = NULL;
    this->_ndTail = NULL;
    this->_nLength = 0;
}

template<class DataO> 
Dlist<DataO> :: ~Dlist()
{
    // Check if we have nodes to delete
    if (this->_nLength > 0);
    {
        this->Clear();
    }
}

/* --- Methods -- */
template<class DataO> 
int Dlist<DataO> :: Length()
{
    // Return the length
    return (this->Length);
}
template<class DataO> 
void Dlist<DataO> :: Add(DataO doData)
{
// Check if head is null
if (this->_ndHead == NULL)
{
    // Create head
    this->_ndHead = new Node<DataO>(doData, NULL, NULL);
}
// Check if tail is null
else if (this->_ndTail == NULL)
{
    // Create tail
    this->_ndTail = new Node<DataO>(doData, NULL, this->_ndHead);

    // Set head's next
    this->_ndHead->SetNext(this->_ndTail);
}
// Create a new Node and replace the tail.
else
{
    // Create a new node.
    this->_ndTail->_ndNext = new Node<DataO>(doData, NULL, this->_ndTail);

    // Make the new node the tail
    this->_ndTail = this->_ndTail->_ndNext;
}
}

ノード H:

    template<class DataO> 
class Node
{
private:
    /* Data Members */
    DataO  _doData;
    Node<DataO>*  _ndPrev;
    Node<DataO>*  _ndNext;

    /* Methods */
    void Delete();

public:
    /* Ctors && Dtors */
    Node<DataO>(DataO doData);
    Node<DataO>(DataO doData, const Node& ndNext, const Node& ndPrev);
    ~Node();

    /* Getters && Setters */
    DataO&  GetData();
    void    SetData(DataO doData);

    const Node& GetNext();
          void  SetNext(const Node* ndNextNode);
    const Node& GetPrev();
          void  SetPrev(const Node* ndPrevNode);
};

ノード Cpp:

// Node.cpp

#include "Node.h"

/* ------------------ Node Section ------------------ */
/* --- Constracturs --- */
template<class DataO> 
Node<DataO> :: Node(DataO doData)
{
    // Init data
    this->SetData(doData);
    this->SetNext(NULL);
    this->SetPrev(NULL);
}

template<class DataO> 
Node<DataO> :: Node(DataO doData, const Node& ndNext, const Node& ndPrev) 
{
    // Init data
    this->SetData(doData);
    this->SetNext(ndNext);
    this->SetPrev(ndPrev);
}

/*
    -   Node destructor -
    -   Maneges the change of nodes.
    -   Changes the Previous node next node, 
    -   to the current node next node.
*/
template<class DataO> 
Node<DataO> :: ~Node()
{
    // Check that prev is not null
    if (this->GetPrev != NULL)
    {
        // Set prevs Next to current next
        this->GetPrev().SetNext(this->GetNext());
    }
}

/*
    -   GetData -
    -   Returns the data stored in the Node.
*/
template<class DataO> 
DataO& Node<DataO> :: GetData()
{
    // Return the data
    return (this->_doData&);
}

/*
    -   SetData -
    -   Sets the data stored in the Node.
*/
template<class DataO> 
void Node<DataO> :: SetData(DataO doData)
{
    // Sets data
    this->_doData = doData;
}

/*
    -   GetNext -
    -   Returns the next node in the list.
*/
template<class DataO> 
const Node<DataO>& Node<DataO> :: GetNext()
{
    // Returns the next node in the list.
    return (this->_ndNext&);
}

/*
    -   SetNext -
    -   Set the next node in the list.
*/
template<class DataO> 
void Node<DataO> :: SetNext(const Node* ndNextNode)
{
    // Set next node as given node
    this->_ndNext = ndNextNode;
}

/*
    -   GetPrev -
    -   Returns the previous node in the list.
*/
template<class DataO> 
const Node<DataO>& Node<DataO> :: GetPrev()
{
    // Returns the next node in the list.
    return (this->_ndPrev&);
}

/*
    -   SetPrev -
    -   Set the previous node in the list.
*/
template<class DataO> 
void Node<DataO> :: SetPrev(const Node* ndPrevNode)
{
    // Set next node as given node
    this->GetPrev = ndPrevNode;
}
4

1 に答える 1

1

これは、MSVC コンパイラが extern テンプレートをサポートしていないために発生します。あなたの考えはわかりますが、これは正しいアプローチですが、ほとんどのコンパイラでは機能しません。これは、テンプレートのインスタンス化ごとにコードを生成するために、コンパイラが (署名だけでなく) テンプレート定義全体にアクセスする必要があるためです。動作させるには 2 つのオプションがあります。

  1. ヘッダー ファイルですべてのメソッドを定義します (ほとんどの Boost ライブラリが行うように)

  2. 事前定義された型のテンプレート クラスを明示的にインスタンス化します (この方法では、クラスはジェネリックではなくなります)。

詳しい説明はこちら

于 2012-09-21T18:32:42.393 に答える