嵌套重载<< 以及模板特化的使用

       我在用c++实现一个链式栈的时候,我想用c++特别的重载方式,实现对栈的一个对象的输出,例如 stack<int> st ;     cout<<st;  然而实现这一个小小的重载真的很艰辛

代码如下:

#pragma once
#include <iostream>
#include <fstream>
#include <assert.h>
using namespace std;
template<class Type>
class stack;
//template<class Type>
//class ListNode;
//template<class Type>
//ostream& operator<<(ostream& ou, ListNode<Type>& r);
template<class Type>
class ListNode
{
	friend class stack<Type>;
public:
	ListNode() :data(Type()), link(NULL)
	{}
	ListNode(Type d, ListNode<Type>* next = NULL) :data(d), link(next)
	{}
	~ListNode()
	{}
	friend ostream& operator<< <Type>(ostream& ou, ListNode<Type>& r);
	friend ostream& operator<< <Type>(ostream& out, stack<Type>& R);
private:
	Type                data;
	ListNode<Type>*      link;
};
//template<class Type>
//ostream& operator<<(ostream& out, stack<Type>& R);
template<class Type>
class stack
{
public:
	stack()
	{
		top = NULL;
	}
	~stack()
	{
		Destroy();
	}
public:
	bool Empty()
	{
		return top == NULL;
	}
	void Push(Type x)
	{
		if (Empty())
		{
			top = new ListNode<Type>(x);
		}
		else
		{
			top = new ListNode<Type>(x, top);
		}
	}
	/*void Show()
	{
		if (Empty())
		{
			return;
		}
		else
		{
			ListNode<Type>* cur = top;
			while (cur != NULL)
			{
				cout << cur->data << " ";
				cur = cur->link;
			}
		}
		cout << endl;
	}*/
	void Pop()
	{
		if (Empty())
		{
			return;
		}
		else
		{
			ListNode<Type>* rm = top;
			top = top->link;
			delete rm;
		}
	}
	void Pop(Type& e)
	{
		if (Empty())
		{
			return;
		}
		else
		{
			e = top->data;
			ListNode<Type>* rm = top;
			top = top->link;
			delete rm;
		}
	}
	Type Gettop()
	{
		if (Empty())
			return NULL;
		else
			return top->data;
	}
	int Length()
	{
		int count = 0;
		if (Empty())
		{
		}
		else
		{
			ListNode<Type>* cur = top;
			while (cur != NULL)
			{
				count++;
				cur = cur->link;
			}
		}
		return count;
	}
	void Destroy()
	{
		if (Empty())
		{
			return;
		}
		else
		{
			ListNode<Type>* rm = top;
			while (top != NULL)
			{
				rm = top;
				top = top->link;
				delete rm;
			}
		}
	}
  friend ostream& operator<< <Type>(ostream& out, stack<Type>& R);
private:
	ListNode<Type>*  top;
};
template<class Type>
ostream& operator<<(ostream& ou, ListNode<Type>& r)
{
		ou << r.data;
		return ou;
}
template<class Type>
ostream& operator<<(ostream& out, stack<Type>& R)
{
	out << "top:";
	ListNode<Type>* cur = R.top;
	while (cur != NULL)
	{
		out << *cur;
		out << " ";
		cur = cur->link;
	}
	out << "base";
	out << endl;
	return out;
}
//测试代码

#include "stack.h"
int main()
{
    stack st;
    st.Push(23);
    st.Push(24);
    st.Push(25);
    st.Push(26);
    cout << st;
    st.Push(27);
    cout << st;
    int a=st.Gettop();
    cout << a << endl;
    st.Pop();
    cout << st;
    return 0;
}

通过写这个stack我发现一些东西还是需要把握的。

1.在实现的时候可以只将stack封装起来,而把ListNode暴露出来,这样可以方便很多。否则数据的实现特别麻烦,首先stack必须为ListNode的友元类,其次还是为了访问ListNode的私有成员,我不得不把stack的友元函数在ListNode类里卖弄声明一下,大家如果看的仔细的话,应该有下面两条语句。

friend ostream& operator<< (ostream& ou, ListNode& r);
friend ostream& operator<< (ostream& out, stack& R);

为了访问ListNode的私有数据我们做了很复杂的处理,如果ListNode是公有的,那么访问起来方便多了,而且我们主要的实现方法都是在stack里面实现的,而我们把stack封装起来就行了。

2.

friend ostream& operator<< <Type>(ostream& ou, ListNode<Type>& r); 

friend ostream& operator<< <Type>(ostream& out, stack<Type>& R); 

相信我们自己写这两个函数的时候都会缺少了红色字体的<Type>标志吧,它在这里起到特化作用,这两个声明需要特化<Type>,否则编译器会找不到该标识符,这个是导致我很久都没实现出来的主要原因。
3.而且我在实现的时候看过c++primer中的有关友元函数的部分,它讲到若一个友元函数能被类的一个对象所访问的话,那么需要提前先声明一下,就像我在开始注释的那几段代码那样。但实际上是取决于编译器,在vs2013中不需要提前声明可以运行,但是在linux的vim平台中则需要提前声明,否则无法编译。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值