posts - 23,  comments - 43,  trackbacks - 1
公告
    很简单的一个列表类,而且并不是很完善,仅限于在自己的程序中使用。有很多很基本的东西还没搞懂。不过我一直奇怪的是:我将这个类的声明和实现放在不同的文件中时(.h, .cpp),最后在引用用这个类的地方都会出现连接错误,无奈只能将声明和实现放在同一个文件中了(.h),模板类的编译和连接机制到底是怎样的呢?
#pragma once

template
<typename NodeType>
class TQueue;

template 
<typename NodeType>
class QNode
{
public:
    NodeType 
* node;
    QNode
<NodeType> * nextQNode;
    QNode
<NodeType> * prevQNode;
    friend 
class TQueue<NodeType>;
}
;

template 
<typename NodeType>
class TQueue  
{
public:
    TQueue(
void);
    
~TQueue(void);

    WORD GetCount();

    
// Queue Behavior
    NodeType * PickHead();
    
void AppendTail(NodeType * _newNode);
    BOOL IsEmpty();

    
// Sequence Visit
    NodeType * GetNextNode(HANDLE & hcur);
    NodeType 
* PickCurrentNode(HANDLE & hcur);

private:
    WORD _queueLen;
    QNode
<NodeType> * _queueHead, * _queueTail;
}
;


/// --- imp --- ///
template <typename NodeType>
TQueue
<NodeType>::TQueue(void)
{
    _queueLen 
= 0;
    _queueHead 
= NULL;
    _queueTail 
= NULL;
}


template 
<typename NodeType>
TQueue
<NodeType>::~TQueue(void)
{
    NodeType 
* tmpNode = NULL;
    
while(_queueLen>0)
    
{
        tmpNode 
= PickHead();
        delete tmpNode;
    }

}


template 
<typename NodeType> 
WORD TQueue 
<NodeType>::GetCount()
{
    
return _queueLen;
}


// Queue Behavior
template <typename NodeType>
NodeType 
* TQueue<NodeType>::PickHead()
{
    
if(_queueLen == 0)return NULL;
    assert(_queueHead 
!= NULL);

    QNode
<NodeType> * tmpQNode = _queueHead;
    NodeType 
* tmpNode = NULL;

    
if(_queueHead->nextQNode != NULL) // has node lest
    {
        _queueHead
->nextQNode->prevQNode = NULL;
    }

    
else _queueTail = NULL; // no nodes left, so set _queueTail = NULL;
    _queueHead = _queueHead->nextQNode;

    _queueLen
--;
    
    tmpNode 
= tmpQNode->node;
    delete tmpQNode;
    
return tmpNode;
}


template 
<typename NodeType>
void TQueue<NodeType>::AppendTail(NodeType * _newNode)
{
    QNode
<NodeType> * newQNode = new QNode<NodeType>;
    newQNode
->node = _newNode;
    newQNode
->nextQNode = NULL;
    
if(_queueLen == 0// Empty Queue
    {
        newQNode
->prevQNode = NULL;
        _queueHead 
= newQNode;
        _queueTail 
= newQNode;
        _queueLen 
++;
        
return;
    }

    
// Queue not Empty
    assert(_queueTail != NULL);
    _queueTail
->nextQNode = newQNode;
    newQNode
->prevQNode = _queueTail;
    _queueTail 
= newQNode;
    _queueLen 
++;
}


template 
<typename NodeType>
BOOL TQueue
<NodeType>::IsEmpty()
{
    
return (_queueLen==0);
}


// Sequence Visit
template <typename NodeType>
NodeType 
* TQueue<NodeType>::GetNextNode(HANDLE & hcur)
{
    
if (hcur == 0x0000)
    
{
        hcur 
= (HANDLE)_queueHead;
        
if(_queueHead != NULL) return _queueHead->node;
        
else return NULL;
    }


    QNode
<NodeType> * tmpQNode = (QNode<NodeType>*)hcur;
    
if(tmpQNode->nextQNode == NULL)
    
{
        hcur 
= 0x0000;
        
return NULL;
    }

    
else
    
{
        hcur 
= (HANDLE)tmpQNode->nextQNode;
        
return (tmpQNode->nextQNode->node);
    }

}


template 
<typename NodeType>
NodeType 
* TQueue<NodeType>::PickCurrentNode(HANDLE & hcur)
{
    assert(hcur 
!= NULL);
    assert(_queueLen 
> 0);

    QNode
<NodeType> * tmpQNode = (QNode<NodeType>*)hcur;
    NodeType 
* tmpNode = NULL;

    
if (tmpQNode->prevQNode == NULL) // is the head
        _queueHead = tmpQNode->nextQNode;
    
else
        tmpQNode
->prevQNode->nextQNode = tmpQNode->nextQNode;

    
if (tmpQNode->nextQNode == NULL) // is the tail
        _queueTail = tmpQNode->prevQNode;
    
else
        tmpQNode
->nextQNode->prevQNode = tmpQNode->prevQNode;

    tmpNode 
= tmpQNode->node;
    delete tmpQNode;
    hcur 
= NULL;
    
return tmpNode;
}
posted on 2004-11-12 13:49 玄驹子 阅读(...) 评论(...) 编辑 收藏