Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于我的模板链接列表_C++_Templates_Data Structures_Containers - Fatal编程技术网

C++ 关于我的模板链接列表

C++ 关于我的模板链接列表,c++,templates,data-structures,containers,C++,Templates,Data Structures,Containers,有点奇怪的是,不久前我成功地实现了自己的模板链接列表,作为一种教育练习。现在我知道它是有效的,我一直在用它创建一个包含“精灵”对象的节点列表,当时我理解它,但今天我去回顾它,我真的很困惑 如果你能看看我的实现并帮我弄清楚 程序如何知道_数据(在节点中)应该被分配一个节点类型的对象??(如果你能原谅我拙劣的措辞)我的意思是我有这个函数SetData,但我从来没有使用过它。例如,当我向后推列表时,我只是创建一个ListType的新节点,但我从未设置该节点的数据。节点构造函数没有说\u data=ne

有点奇怪的是,不久前我成功地实现了自己的模板链接列表,作为一种教育练习。现在我知道它是有效的,我一直在用它创建一个包含“精灵”对象的节点列表,当时我理解它,但今天我去回顾它,我真的很困惑

如果你能看看我的实现并帮我弄清楚

程序如何知道_数据(在节点中)应该被分配一个节点类型的对象??(如果你能原谅我拙劣的措辞)我的意思是我有这个函数
SetData
,但我从来没有使用过它。例如,当我向后推列表时,我只是创建一个ListType的新节点,但我从未设置该节点的数据。节点构造函数没有说
\u 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
#如果!已定义节点\u水电站
#定义节点_水电站
模板
类节点{
公众:
节点(节点*prev=0,节点*next=0);
void SetData(节点类型newData);
NodeType*GetData();
节点*GetPrev();
节点*GetNext();
私人:
模板
好友类列表;
节点类型数据;
节点*_prev;
节点*\u下一步;
};
///实现节点
模板
Node::Node(Node*prev,Node*next):\u prev(prev),\u next(next)
{}
模板
void Node::SetData(NodeType newData)
{
_数据=新数据;
}
模板
NodeType*节点::GetData()
{
返回&u数据;
}
模板
Node*Node::GetPrev()
{
返回上一页;
}
模板
Node*Node::GetNext()
{
返回下一步;
}
#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
#如果!已定义列表\u水电站
#定义列表\u水电站
#包括“Node.hpp”
///因为我们正在创建模板,所以所有内容都必须在hpp中定义
模板
班级名单
{
公众:
List();
bool Empty();
void PushFront();
无效回推();
void PopBack();
void ClearList();
节点*GetHead();
节点*GetTail();
int NumberOfNodes();
私人:
节点*头;
节点*_尾;
内部尺寸;
};
///在这里实现列表类
模板
列表::列表():_头(0),_尾(0),_大小(0)
{
}
模板
bool List::Empty()
{
返回_size==0;
}
模板
无效列表::PushFront()
{
_头=新节点(_头,0);
如果(Empty())//这是新列表的开始,还需要设置_tail
_尾巴=头;
其他的
_head->\U prev->\U next=\U head;//设置前一个节点\U next到新\U head
++_大小;
}
模板
void List::PushBack()
{
_tail=新节点(0,_tail);
如果(Empty())//这是新列表的开始,还需要设置_head
_头=尾;
其他的
_tail->\u next->\u prev=\u tail;//设置旧tail\u prev为新tail
++_大小;
}
模板
void List::PopBack()
{
如果(!Empty()){
如果(_tail!=_head)
{
_tail=\u tail->\u next;
delete _tail->_prev;//删除旧tail处的内存
_tail->\u prev=0;//重新分配新的tail\u prev指针为null
}
else//我们正在删除最后一个节点,因此处理方式略有不同。
{
删除尾;
_尾=0;_头=0;
}
--_大小;
}
}
模板
void List::ClearList()
{
而(!Empty())
弹回();
}
模板
节点*列表::GetHead()
{
返回头;
}
模板
节点*列表::GetTail()
{
返回尾;
}
模板
int List::NumberOfNodes()
{
返回大小;
}
#endif//define

构造函数没有显式地对
\u数据执行任何操作,因此默认情况下会初始化它*。换句话说,在构造之后,
\u data
是默认构造的
节点类型。它
NodeType
不是默认可构造的,模板专用化不会编译。这个程序“知道”来做这个初始化,因为希望你的编译器遵循C++标准中规定的规则。 至于了解类型,编译器基本上会替换您实例化模板时使用的任何类型,并使用此替换创建一个新类型。因此,
节点将产生一种类型,其中
\u data
的类型为
std::string`

  • 如果
    NodeType
    是一个promitive类型,则不会进行初始化,
    \u data
    将保存任何旧的垃圾值

关于数据是如何知道类型的?啊,谢谢,我花了一些时间,但我现在和你在一起了!为指出数据是节点类型而欢呼,因此,如果没有初始化,将只是任何节点类型的默认构造函数!