0

少し奇妙なことに、私はしばらく前に教育演習として自分のテンプレート化されたリンクリストを正常に実装しました。これで動作することがわかったので、「スプライト」オブジェクトを保持するノードのリストを作成するために使用していました。当時は理解していましたが、今日行って振り返ると、本当に混乱しています。

あなたが私の実装を見て、私が理解するのを手伝ってくれるのに十分親切であるなら。

プログラムは、(ノード内の)_dataにNodeTypeのオブジェクトを割り当てる必要があることをどのように認識しますか?(言い回しの悪さを許せば)私はその機能を持っているということですSetDataが、私はそれを使用することさえありません。たとえば、リストをプッシュバックすると、ListTypeの新しいノードを作成するだけですが、そのノードのデータを設定することはありません。ノードコンストラクターは何も言いません_data = new NodeType

それでもGetData()、リスト内の任意のノードを呼び出して、Spriteオブジェクトを取り戻すことができます。私はそれが機能することを知っているという意味ですが、私は方法を忘れました!誰かが見て、私に思い出させることができますか?よろしくお願いします!

Node.hpp:

#if !defined NODE_HPP
#define NODE_HPP


template<typename NodeType>
class Node{

   public:
      Node( Node* prev = 0, Node* next = 0);
      void SetData(NodeType newData);
      NodeType* GetData();
      Node* GetPrev();
      Node* GetNext();

   private:
      template<typename ListType>
      friend class List;

      NodeType _data;
      Node* _prev;
      Node* _next;

};


///implement Node

template <typename NodeType>
Node<NodeType>::Node(Node* prev, Node* next) : _prev(prev), _next(next)
{}
template <typename NodeType>
void Node<NodeType>::SetData(NodeType newData)
{
   _data = newData;
}
template <typename NodeType>
NodeType* Node<NodeType>::GetData()
{
   return &_data;
}
template <typename NodeType>
Node<NodeType>* Node<NodeType>::GetPrev()
{
   return _prev;
}
template <typename NodeType>
Node<NodeType>* Node<NodeType>::GetNext()
{
   return _next;
}
#endif //define

List.hpp

#if !defined LIST_HPP
#define LIST_HPP

#include "Node.hpp"

///since we're creating a template everything must be defined in the hpp

template <typename ListType>
class List
{
   public:
      List();
      bool Empty();
      void PushFront();
      void PushBack();
      void PopBack();
      void ClearList();
      Node<ListType>* GetHead();
      Node<ListType>* GetTail();
      int NumberOfNodes();

   private:
      Node<ListType>* _head;
      Node<ListType>* _tail;
      int _size;

};


///implement List class here
template <typename ListType>
List<ListType>::List() : _head(0), _tail(0), _size(0)
{
}
template <typename ListType>
bool List<ListType>::Empty()
{
   return _size == 0;
}
template <typename ListType>
void List<ListType>::PushFront()
{
   _head = new Node<ListType>( _head , 0 );
   if(Empty()) //this is the start of a new list, need to set _tail as well
      _tail = _head;
   else
      _head->_prev->_next = _head; //set previous nodes _next to new _head


   ++_size;
}
template <typename ListType>
void List<ListType>::PushBack()
{
   _tail = new Node<ListType>( 0 , _tail);
   if(Empty()) //this is the start of a new list, need to set _head as well
      _head = _tail;
   else
      _tail->_next->_prev = _tail; // set old tails _prev to new tail

   ++_size;
}
template <typename ListType>
void List<ListType>::PopBack()
{
   if(!Empty()){
      if(_tail != _head)
      {
         _tail = _tail->_next;
         delete _tail->_prev; //delete memory at old tail
         _tail->_prev = 0; //reassign new tails _prev pointer to null
      }
      else  // We are deleting the last node so treatment is a little different.
      {
         delete _tail;
         _tail = 0; _head = 0;
      }

      --_size;
   }
}
template <typename ListType>
void List<ListType>::ClearList()
{
   while(!Empty())
      PopBack();


}

template <typename ListType>
Node<ListType>* List<ListType>::GetHead()
{
   return _head;
}
template <typename ListType>
Node<ListType>* List<ListType>::GetTail()
{
   return _tail;
}
template <typename ListType>
int List<ListType>::NumberOfNodes()
{
   return _size;
}
#endif //define
4

1 に答える 1

1

コンストラクターは明示的に何もしない_dataので、デフォルトで初期化されます*。つまり、構築後_dataは、デフォルトで構築されNodeTypeます。これNodeTypeはデフォルトで構築可能ではなく、テンプレートの特殊化はコンパイルされませんでした。プログラムは、この初期化を行うことを「認識」しています。これは、コンパイラがC++標準で設定されたルールに従っていることを願っています。

タイプを知ることに関しては、コンパイラーは基本的に、テンプレートをインスタンス化するタイプを置き換え、この置き換えNodeTypeを使用して新しいタイプを作成します。したがって、Node<std::string> would result in a type where_data is of typestd::string`です。

  • NodeTypeプロミティブタイプの場合、初期化は行われず、_data古いガベージ値が保持されます。
于 2012-05-06T13:44:59.613 に答える