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元素的前提下,访问任何一个元素。
先分析一下,一共有这几件事情要做:
-
- 基类是个纯抽象类 stack,只提供最简单的接口:
pop()、push()、size()、empty()、full()、peek()和print()
;
- 基类是个纯抽象类 stack,只提供最简单的接口:
-
- 派生类LIFO_stack;
-
- 派生类Peekbackstack;
-
- 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专业版;
共勉!
上一篇: 部署 zookeeper+kafka 消息队列集群
下一篇: Java 面试问题 书面问题。