[ create a new paste ] login | about

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

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

#include <cstdlib>
#include <iostream>

template <typename TYPE> class CStackNode;  // スタック要素
template <typename TYPE> class CStack;      // スタック

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

};

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

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

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

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

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

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

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

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

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

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

/*---------------------------------------------------------------------------*/
/*  CStack: Methods                                                          */
/*---------------------------------------------------------------------------*/
template <typename TYPE>
void CStack<TYPE> ::Push(const TYPE& data)
{
	CStackNode<TYPE>* newnode;
	
	newnode = new CStackNode<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>
TYPE CStack<TYPE>::Pop()
{
	if (m_topnode == false) {
		std::cout << "error: Pop: stack underflow." << std::endl;
		exit(0);
	}
	CStackNode<TYPE>    *prevnode;
	TYPE                data;
	
	data = m_topnode->m_data;           // データを返す準備
	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--;                          // 要素数をデクリメント
	
	return data;
}

template <typename TYPE>
TYPE& CStack<TYPE>::Top()
{
	if (m_topnode != NULL)
		return m_topnode->m_data;
	else {
		std::cout << "error: CStack: TYPE& Top: m_topnode is null." << std::endl;
		exit(0);
	}
}

template <typename TYPE>
const TYPE& CStack<TYPE>::Top() const
{
	if (m_topnode != NULL)
		return m_topnode->m_data;
	else {
		std::cout << "error: CStack: TYPE& Top: m_topnode is null." << std::endl;
		exit(0);
	}
}


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


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

template<typename TYPE>
void CStack<TYPE> ::Copy(const CStack<TYPE>& rother)
{
	CStackNode<TYPE> *thisnode, *newnode;
	
	for (thisnode = rother.m_lownode; thisnode != NULL; thisnode = thisnode->m_nextnode)
	{
		newnode = new CStackNode<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;
}

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

#endif//__STACK_H_INCLUDED__


Create a new paste based on this one


Comments: