美文网首页
类模板实例(含有友元成员函数模板)

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

作者: IT孤独者 | 来源:发表于2017-02-04 14:46 被阅读0次

    首先说下感受,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;
    }
    

    相关文章

      网友评论

          本文标题:类模板实例(含有友元成员函数模板)

          本文链接:https://www.haomeiwen.com/subject/wtnjittx.html