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

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

作者: 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;
}

相关文章

  • 10-C++远征之模板篇-学习笔记

    C++远征之模板篇 将会学到的内容: 模板函数 & 模板类 -> 标准模板类 友元函数 & 友元类 静态数据成员 ...

  • 慕课网-C++远征之模板篇(上)-学习笔记

    C++远征之模板篇 将会学到的内容: 模板函数 & 模板类 -> 标准模板类 友元函数 & 友元类 静态数据成员 ...

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

    首先说下感受,C++的流式输入输出某种程度上比C的标准输入输出要简洁,但是,并不简单,我说不简单的原因是C++因为...

  • 14/15

    约束模板友元 模板类的外边定义一个模板函数,在模板类中将模板函数具体化为模板类的友元函数 非约束模板友元 模板类中...

  • 类模板中的友元函数

    今天写cpp的时候,忘记了类模板中的友元怎么用了记录一下 先声明类模板,和友元函数 类模板中声明友元函数 类模板外...

  • 14/14模板和友元之非模板友元

    1.非模板友元:将模板类中的函数作为友元

  • 14/12

    成员模板:模板类中成员变量是模板类对象(1),模板类中函数是模板函数(2)

  • 【C++ Templates(2)】类模板

    类模板示例 使用类模板 模板实参可以是任何类型 成员函数只有被调用到时才实例化 如果类模板有static数据成员,...

  • 02 类模板

    类模板示例 使用类模板 模板实参可以是任何类型 成员函数只有被调用到时才实例化 如果类模板有static数据成员,...

  • 模板与泛型 —— using 定义模板别名

    一、类的成员函数模板 二、using 定义模板别名 一、类的成员函数模板 普通类和模板类,其成员函数都可以是模板函...

网友评论

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

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