欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

C++ 代码编程学习:基于对象的编程风格 - 练习 5.1(Essential C++ 第 5 章) - II.示例

最编程 2024-07-16 13:57:28
...

-P238 练习 5.1
  实现一个两层的 stack(堆栈)类体系。其基类是个纯抽象类 stack,只提供最简单的接口: pop()、push()、size()、empty()、full()、peek()和print() 。两个派生类则为LIFO_stack 和Peekbackstack。peekback stack可以让用户在不更改stack元素的前提下,访问任何一个元素。

先分析一下,一共有这几件事情要做:

    1. 基类是个纯抽象类 stack,只提供最简单的接口: pop()、push()、size()、empty()、full()、peek()和print()
    1. 派生类LIFO_stack;
    1. 派生类Peekbackstack;
    1. peekback stack可以让用户在不更改stack元素的前提下。

原书作者解析到:两个派生类都以vector来负责元素储存任务。为了打印vector的内容,我采用一个const_reverse_iterator,此iterator可以逆向方式由尾端至前端遍历整个vector。

代码如下:


#include <string>
#include <iostream>
#include <vector>

using namespace std;

typedef string elemType;

class Stack
{
public:
    virtual ~Stack() {};
    virtual bool pop(elemType&) = 0;
    virtual bool push(const elemType&) = 0;
    virtual bool peek(int index, elemType&) = 0;

    virtual int top() const = 0;
    virtual int size() const = 0;

    virtual bool empty() const = 0;
    virtual bool full() const = 0;
    virtual void print(ostream & = cout) const = 0;

};

ostream& operator<<(ostream& os, const Stack& rhs)
{
    rhs.print();
    return os;
}

class LIFO_Stack : public Stack
{
public:
    LIFO_Stack(int capacity = 0) : _top(0)
    {
        // 逆向方式由尾端至前端遍历整个vector
        if (capacity) _stack.reserve(capacity);
    }
    int size() const { return _stack.size(); }
    bool empty() const { return !_top; }
    bool full() const { return size() >= _stack.max_size(); }
    int top() const { return _top; }
    void print(ostream& os = cout) const;

    bool pop(elemType& elem);
    bool push(const elemType& elem);
    bool peek(int index, elemType&) { return false; }

private:
    vector<elemType> _stack;
    int _top;

};


void LIFO_Stack::print(ostream& os) const
{
    vector<elemType>::const_reverse_iterator
        rit = _stack.rbegin(), rend = _stack.rend();
    os << "\n\t";
    while (rit != rend)
        os << *rit++ << "\n\t";
    os << endl;
}

bool LIFO_Stack::pop(elemType& elem)
{
    if (empty()) return false;
    elem = _stack[--_top]; // 弹出一个元素,指针减一
    _stack.pop_back();
    return true;
}
bool LIFO_Stack::push(const elemType& elem)
{
    if (full()) return false;
    _stack.push_back(elem);
    ++_top;
    return true;
}


class Peekback_Stack : public Stack
{
public:
    Peekback_Stack(int capacity = 0) : _top(0)
    {
        // 逆向方式由尾端至前端遍历整个vector
        if (capacity) _stack.reserve(capacity);
    }
    int size() const { return _stack.size(); }
    bool empty() const { return !_top; }
    bool full() const { return size() >= _stack.max_size(); }
    int top() const { return _top; }
    void print(ostream& os = cout) const;

    bool pop(elemType& elem);
    bool push(const elemType& elem);
    bool peek(int index, elemType& elem);

private:
    vector<elemType> _stack;
    int _top;

};

void Peekback_Stack::print(ostream& os) const
{
    vector<elemType>::const_reverse_iterator
        rit = _stack.rbegin(), rend = _stack.rend();
    os << "\n\t";
    while (rit != rend)
        os << *rit++ << "\n\t";
    os << endl;
}

bool Peekback_Stack::pop(elemType& elem)
{
    if (empty()) return false;
    elem = _stack[--_top]; // 弹出一个元素,指针减一
    _stack.pop_back();
    return true;
}
bool Peekback_Stack::push(const elemType& elem)
{
    if (full()) return false;
    _stack.push_back(elem);
    ++_top;
    return true;
}


bool Peekback_Stack::peek(int index, elemType& elem)
{
    if (empty()) return false;
    if ((index < 0) || (index >= size())) return false;
    elem = _stack[index];
    return true;
}

void peek(Stack& st, int index)
{
    cout << endl;
    string t;
    if (st.peek(index, t))
        cout << "peek: " << t;
    else
        cout << "peek failed!";
    cout << endl;
}

int main()
{
    LIFO_Stack st;
    string str;
    while (cin >> str && !st.full())
        st.push(str);
    cout << '\n' << "About to call peek() with LIFO_Stack" << endl;
    peek(st, st.top() - 1);
    cout << st;

    Peekback_Stack pst;
    while (!st.empty())
    {
        string t;
        if (st.pop(t))
            pst.push(t);
    }
    cout << '\n' << "About to call peek() with Peekback_Stack" << endl;
    peek(pst, pst.top() - 1);
    cout << pst;


}

  • 这道题非常的赞哦,虚函数有点基础样板的意思,也就是派生类都需要用,我提前在基类里提一嘴的意思,其中有关while (cin >> str && !st.full())输入的问题,可以看我的另外一篇blog:C++代码编程学习:基于对象的编程风格——Stack学习(Essential C++ 第四章),加油,继续努力,可以开始下一章了。

在这里插入图片描述

代码是在 visual studio 中编写的,该软件还是比较好用的,我安装的是2022专业版;

共勉!