首先说下感受,C++的流式输入输出某种程度上比C的标准输入输出要简洁,但是,并不简单,我说不简单的原因是C++因为要使用这个流特性,产生了不太一样的编程范式,比如友元范式,流类的运算符重载只能是友元,另外流类都是不可拷贝。
模板中重载这个运算符的时候的范式更是诡异,反正我是没有弄明白,暂时先解释到这里。毕竟这不会影响对C++的整体的印象!
Queue.h
#pragma once
#include <iostream>
#include <assert.h>
using std::ostream;
using std::istream;
template<typename T>
class QueueItem
{
public:
QueueItem();
~QueueItem();
void setContext(const T & data);
T & getContext();
void setNext(QueueItem<T> * ptr);
QueueItem<T> * getNext();
private:
QueueItem(const QueueItem<T> &);
QueueItem<T> & operator= (const QueueItem<T> &);
private:
T * context;
QueueItem<T> * next;
};
template<typename T>
class Queue
{
public:
Queue();
Queue(const Queue &);
Queue<T> & operator= (const Queue &);
~Queue();
T & front();
T & back();
void pop();
void push(const T &);
int isEmpty();
friend ostream & operator<< <T> (ostream & os, const Queue<T> & q);
friend istream & operator>> <T> (istream & os, Queue<T> & q);
private:
void destory();
void copyItems(const Queue & other);
private:
QueueItem<T> * head;
QueueItem<T> * tail;
};
template<typename T>
Queue<T>::Queue()
{
head = nullptr;
tail = nullptr;
}
template<typename T>
inline Queue<T>::Queue(const Queue & other)
{
head = nullptr;
tail = nullptr;
copyItems(other);
}
template<typename T>
inline Queue<T> & Queue<T>::operator=(const Queue & other)
{
// TODO: insert return statement here
destory();
copyItems(other);
}
template<typename T>
inline Queue<T>::~Queue()
{
destory();
}
template<typename T>
inline T & Queue<T>::front()
{
// TODO: insert return statement here
assert(!isEmpty());
return head->getContext();
}
template<typename T>
inline T & Queue<T>::back()
{
// TODO: insert return statement here
assert(!isEmpty());
return tail->getContext();
}
template<typename T>
inline void Queue<T>::pop()
{
if (isEmpty()) return;
auto pTmp = head;
head = head->getNext();
if (isEmpty()) tail = nullptr;
delete pTmp;
pTmp = nullptr;
}
template<typename T>
inline void Queue<T>::push(const T & data)
{
auto pElem = new QueueItem<T>;
pElem->setContext(data);
pElem->setNext(nullptr);
if (isEmpty()) {
head = tail = pElem;
}
else {
tail->setNext(pElem);
tail = pElem;
}
}
template<typename T>
inline void Queue<T>::destory()
{
while (!isEmpty()) {
pop();
}
}
template<typename T>
inline int Queue<T>::isEmpty()
{
return head == nullptr;
}
template<typename T>
inline void Queue<T>::copyItems(const Queue & other)
{
for (auto p = other->head; p != nullptr; p = p->getNext())
push(p->getContext());
}
template<typename T>
inline QueueItem<T>::QueueItem()
{
context = new T;
next = nullptr;
}
template<typename T>
inline QueueItem<T>::~QueueItem()
{
next = nullptr;
delete context;
}
template<typename T>
inline void QueueItem<T>::setContext(const T & data)
{
*context = data;
}
template<typename T>
inline T & QueueItem<T>::getContext()
{
return *context;
}
template<typename T>
inline void QueueItem<T>::setNext(QueueItem<T>* ptr)
{
next = ptr;
}
template<typename T>
inline QueueItem<T>* QueueItem<T>::getNext()
{
return next;
}
template<typename T>
ostream & operator<< (ostream & os, const Queue<T> & q)
{
for (auto p = q.head; p!=nullptr; p=p->getNext())
os << p->getContext() << " ";
return os;
}
template<typename T>
istream & operator>> (istream & os, Queue<T> & q)
{
T tmp;
while (os >> tmp, !os.eof())
q.push(tmp);
return os;
}
Source.cpp
#include <iostream>
#include <string>
#include "Queue.h"
using namespace std;
void test1()
{
Queue<int> qIntData;
qIntData.push(1);
qIntData.push(2);
qIntData.push(3);
qIntData.push(0);
cout << qIntData << endl;
qIntData.pop();
cout << qIntData << endl;
qIntData.push(4);
cout << qIntData << endl;
}
void test2()
{
Queue<string> qIntData;
cin >> qIntData;
cout << qIntData << endl;
}
int main(int argc, char ** argv)
{
test1();
test2();
return 0;
}
网友评论