[ create a new paste ] login | about

Link: http://codepad.org/1ggMEDl0    [ raw code | fork ]

C++, pasted on Oct 13:
#ifndef __STACK_H_INCLUDED__
#define __STACK_H_INCLUDED__

#include <cstdlib>
#include <iostream>

template <typename TYPE> class StackNode;  // スタック要素
template <typename TYPE> class Stack;      // スタック

/*===========================================================================*/
/*  StackNode:                                                              */
/*===========================================================================*/
template <typename TYPE>
class StackNode
{
public:// メンバ
	StackNode*	m_prevnode; // 前の要素へのポインタ
	StackNode*	m_nextnode; // 次の要素へのポインタ
	TYPE		m_data;     // この要素が持つデータ
	
public:// コンストラクタ
	StackNode(TYPE data);

};

template <typename TYPE>
StackNode<TYPE>::StackNode(TYPE data)
{
	m_data 	   = data;
	m_prevnode = m_nextnode = NULL;
}

/*===========================================================================*/
/*  Stack:                                                                  */
/*===========================================================================*/ 
template <typename TYPE>
class Stack
{
private:// メンバ
	StackNode<TYPE>*	m_lownode;  // スタック最下段要素へのポインタ
	StackNode<TYPE>*	m_topnode;  // スタック最上段要素へのポインタ
	int			m_elems;    // スタックの要素数
	
public:// コンストラクタ&デストラクタ
	Stack();                         // コンストラクタ
	Stack(const Stack<TYPE>& rother);// コピーコンストラクタ
	~Stack();                        // デストラクタ

public:// インライン関数
	inline int  Size() const;   // スタックの要素数
	inline int  Bytes() const;  // スタック全要素のデータのバイト数
	inline bool Empty() const;  // スタックが空なら true

public:// メソッド
	void            Push(const TYPE& data); // スタックへ要素をプッシュ
	void            Pop();                  // スタックから要素をポップ
	TYPE&           Top();                  // スタック最上段要素のデータへの参照を返す
	const TYPE&	Top() const;            //  "
	void            Clear();                // スタックのクリア
	
private:// メソッドその他
	void Init();				// メンバの初期化
	void Copy(const Stack<TYPE>& rother);	// スタックのコピー
	
public:// オペレータのオーバロード
	Stack<TYPE>& operator =(const Stack<TYPE>& rother);    // スタックのコピー
};

/*---------------------------------------------------------------------------*/
/*  Stack: Inline Functions		        			     */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
inline int Stack<TYPE> ::Size() const
{
	return m_elems;
}

template <typename TYPE>
inline int Stack<TYPE> ::Bytes() const
{
	return m_elems * sizeof(TYPE);
}

template <typename TYPE>
inline bool Stack<TYPE> ::Empty() const
{
	return (m_topnode == NULL);
}

/*---------------------------------------------------------------------------*/
/*  Stack: Constructers							     */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
Stack<TYPE> ::Stack()
{
	Init();
}

template <typename TYPE>
Stack<TYPE> ::Stack(const Stack<TYPE>& rother)
{
	Init();
	Copy(rother);
}

/*---------------------------------------------------------------------------*/
/*  Stack: Destructer                                                        */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
Stack<TYPE> ::~Stack()
{
	Clear();
}

/*---------------------------------------------------------------------------*/
/*  Stack: Methods                                                           */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
void Stack<TYPE> ::Push(const TYPE& data)
{
	StackNode<TYPE>* newnode;
	
	newnode = new StackNode<TYPE>( data );	    // 新規要素を確保
	if (m_topnode == NULL) {                    //  スタックが空なら
		m_lownode = m_topnode = newnode;    // 新規要素を最下段と最上段へ
	} else {                                    //  スタックが空でなければ
		m_topnode->m_nextnode	= newnode;  // 最上段要素の次に新規要素を繋げ
		newnode->m_prevnode	= m_topnode;// 新規要素の前に最上段要素を繋げ
		m_topnode        	= newnode;  // 最上段要素を更新
	}
	m_elems++;                                  // 要素数をインクリメント
}

template <typename TYPE>
void Stack<TYPE>::Pop()
{
	if (m_topnode == NULL) {
		std::cout << "error: Pop: stack underflow." << std::endl;
		return;
	}
	StackNode<TYPE>	*prevnode;
	
	prevnode = m_topnode->m_prevnode;   // 要素の削除準備
	delete m_topnode;                   // 要素の削除
                                            // 以下、リンク
	if (prevnode != NULL) {             //  削除要素の前が空でなければ
		prevnode->m_nextnode = NULL;// 次の要素へのポインタをクリアして
		m_topnode = prevnode;       // 最上段要素のポインタを更新
	} else {                            //  削除要素がスタック最下段要素なら
		m_topnode = NULL;           // ポインタを
		m_lownode = NULL;           //	クリア
	}                                   // 以上、リンク
	m_elems--;                          // 要素数をデクリメント
}

template <typename TYPE>
TYPE& Stack<TYPE>::Top()
{
	static TYPE dummy;
	
	if (m_topnode != NULL)
		return m_topnode->m_data;
	else {
		std::cout << "error: Stack: TYPE& Top(): stack underflow." << std::endl;
		return dummy;
	}
}

template <typename TYPE>
const TYPE& Stack<TYPE>::Top() const
{
	static TYPE dummy;
	
	if (m_topnode != NULL)
		return m_topnode->m_data;
	else {
		std::cout << "error: Stack: const TYPE& Top() const: stack underflow." << std::endl;
		return dummy;
	}
}

template<typename TYPE>
void Stack<TYPE> ::Clear()
{
	StackNode<TYPE> *curstack, *delstack;
	
	for (curstack = m_topnode; curstack != NULL; )// 要素を最上段から辿りすべて削除
	{
		delstack = curstack;
		curstack = curstack->m_prevnode;
		delete delstack;
	}   
	Init();// メンバを初期化
}

/*---------------------------------------------------------------------------*/
/*  Stack : Methods etc                                                      */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
void Stack<TYPE> ::Init()
{
	m_lownode = NULL;
	m_topnode = NULL;
	m_elems = 0;
}

template<typename TYPE>
void Stack<TYPE> ::Copy(const Stack<TYPE>& rother)
{
	if (this == &rother)// 自分自身はコピーしない
            return;
	Clear();// スタックをクリア
	
	StackNode<TYPE> *thisnode, *newnode;
	
	for (thisnode = rother.m_lownode; thisnode != NULL; thisnode = thisnode->m_nextnode)
	{
		newnode = new StackNode<TYPE>( thisnode->m_data );
		if (m_topnode == NULL) {
			m_lownode = m_topnode   = newnode;
		} else {
			m_topnode->m_nextnode	= newnode;
			newnode->m_prevnode	= m_topnode;
			m_topnode		= newnode;
		}
	}
	m_elems = rother.m_elems;
}

/*---------------------------------------------------------------------------*/
/*  Stack: Operator Overload                                                 */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
Stack<TYPE>& Stack<TYPE> ::operator =(const Stack<TYPE>& rother)
{
	Copy(rother);
	return *this;
}

#endif//__STACK_H_INCLUDED__


Create a new paste based on this one


Comments: