类模板实例(含有友元成员函数模板)

首先说下感受,C++的流式输入输出某种程度上比C的标准输入输出要简洁,但是,并不简单,我说不简单的原因是C++因为要使用这个流特性,产生了不太一样的编程范式,比如友元范式,流类的运算符重载只能是友元,另外流类都是不可拷贝。

模板中重载这个运算符的时候的范式更是诡异,反正我是没有弄明白,暂时先解释到这里。毕竟这不会影响对C++的整体的印象!

Queue.h

#pragma once
#include 
#include 
using std::ostream;
using std::istream;

template
class QueueItem
{
public:
    QueueItem();
    ~QueueItem();

    void setContext(const T & data);
    T & getContext();

    void setNext(QueueItem * ptr);
    QueueItem * getNext();

private:
    QueueItem(const QueueItem &);
    QueueItem & operator= (const QueueItem &);

private:
    T * context;
    QueueItem * next;
};

template 
class Queue
{
public:
    Queue();
    Queue(const Queue &);
    Queue & operator= (const Queue &);
    ~Queue();

    T & front();
    T & back();

    void pop();
    void push(const T &);

    int isEmpty();

    friend ostream & operator<<  (ostream & os, const Queue & q);
    friend istream & operator>>  (istream & os, Queue & q);

private:
    void destory();
    void copyItems(const Queue & other);

private:
    QueueItem * head;
    QueueItem * tail;
};

template
Queue::Queue()
{
    head = nullptr;
    tail = nullptr;
}

template
inline Queue::Queue(const Queue & other)
{
    head = nullptr;
    tail = nullptr;

    copyItems(other);
}

template
inline Queue & Queue::operator=(const Queue & other)
{
    // TODO: insert return statement here
    destory();

    copyItems(other);
}

template
inline Queue::~Queue()
{
    destory();
}

template
inline T & Queue::front()
{
    // TODO: insert return statement here
    assert(!isEmpty());
    return head->getContext();
}

template
inline T & Queue::back()
{
    // TODO: insert return statement here
    assert(!isEmpty());
    return tail->getContext();
}

template
inline void Queue::pop()
{
    if (isEmpty()) return;

    auto pTmp = head;
    head = head->getNext();
    if (isEmpty()) tail = nullptr;

    delete pTmp;
    pTmp = nullptr;
}

template
inline void Queue::push(const T & data)
{
    auto pElem = new QueueItem;
    pElem->setContext(data);
    pElem->setNext(nullptr);

    if (isEmpty()) {
        head = tail = pElem;
    }
    else {
        tail->setNext(pElem);
        tail = pElem;
    }
}

template
inline void Queue::destory()
{
    while (!isEmpty()) {
        pop();
    }
}

template
inline int Queue::isEmpty()
{
    return head == nullptr;
}

template
inline void Queue::copyItems(const Queue & other)
{
    for (auto p = other->head; p != nullptr; p = p->getNext())
        push(p->getContext());
}

template
inline QueueItem::QueueItem()
{
    context = new T;
    next = nullptr;
}

template
inline QueueItem::~QueueItem()
{
    next = nullptr;
    delete context;
}

template
inline void QueueItem::setContext(const T & data)
{
    *context = data;
}

template
inline T & QueueItem::getContext()
{
    return *context;
}

template
inline void QueueItem::setNext(QueueItem* ptr)
{
    next = ptr;
}

template
inline QueueItem* QueueItem::getNext()
{
    return next;
}

template
ostream & operator<< (ostream & os, const Queue & q)
{
    for (auto p = q.head; p!=nullptr; p=p->getNext())
        os << p->getContext() << " ";
    return os;
}

template
istream & operator>> (istream & os, Queue & q)
{
    T tmp;
    while (os >> tmp, !os.eof())
        q.push(tmp);
    return os;
}

Source.cpp

#include 
#include 
#include "Queue.h"
using namespace std;

void test1()
{
    Queue 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 qIntData;

    cin >> qIntData;

    cout << qIntData << endl;
}


int main(int argc, char ** argv) 
{
    test1();
    test2();

    return 0;
}

你可能感兴趣的:(类模板实例(含有友元成员函数模板))