《C++プログラミング思想》習題16-12解答
4784 ワード
16-12. Modify TStack2.h so that it uses a Standard C++ Library vector as its underlying implementation. Make sure that you don’t change the interface, so that TStack2Test.cpp works unchanged.
元のStackコード:
vectorで再実装されたStackコード:
元のStackコード:
#ifndef TSTACK2_H
#define TSTACK2_H
#include "../require.h"
template<class T>
class Stack{
private:
struct Link{
T* data;
Link* next;
Link(T* dat, Link* nxt):
data(dat), next(nxt){}
}* head;
public:
Stack(): head(0){}
~Stack();
void push(T* dat){
head = new Link(dat, head);
}
T* peek() const{
return head ? head->data : 0;
}
T* pop();
class iterator;
friend class iterator;
class iterator{
private:
struct Stack::Link* p;
public:
iterator(const Stack<T>& tl): p(tl.head){}
iterator(const iterator& tl): p(tl.p){}
iterator(): p(0) {}
bool operator++(){
if(p->next)
p = p->next;
else
p = 0;
return bool(p);
}
bool operator++(int){
return operator++();
}
T* current() const{
if(p)
return p->data;
else
return 0;
}
T* operator->() const{
require(p != 0, "Stack::iterator::operator->() returns 0");
return current();
}
T* operator*() const{
// ?? require ??
return current();
}
operator bool() const{
return bool(p);
}
bool operator==(const iterator&) const{
return p == 0;
}
bool operator!=(const iterator&) const{
return p != 0;
}
};
iterator begin() const{
return iterator(*this);
}
iterator end() const{
return iterator();
}
};
template<class T>
Stack<T>::~Stack(){
while(0 != head)
delete pop();
}
template<class T>
T* Stack<T>::pop()
{
if(0 == head) return 0;
T* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}
#endif //TSTACK2_H
//#include "TStack2.h"
#include "TStack3.h"
#include "../require.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream file("uniform_result.txt");
assure(file, "uniform_result.txt");
Stack<string> textlines;
string line;
while(getline(file, line)){
textlines.push(new string(line));
}
int i = 0;
Stack<string>::iterator it = textlines.begin();
Stack<string>::iterator* it2 = 0;
while(it != textlines.end()){
cout << it->c_str() << endl;
it++;
if(++i == 10){
it2 = new Stack<string>::iterator(it);
}
}
cout << "line 10: " << endl;
cout << (*it2)->c_str() << endl;
delete it2;
}
vectorで再実装されたStackコード:
#ifndef _TSTACK3_H
#define _TSTACK3_H
#include "../require.h"
#include <vector>
using namespace std;
template<typename T>
class Stack{
public:
Stack(){};
~Stack();
void push(T* dat){
_vec.push_back(dat);
}
T* peek() const{
if(_vec.size() <= 0)
return 0;
//vector<T*>::iterator it = _vec.end();
//it--;
vector<T*>::iterator it = _vec.rbegin();
return *it;
}
T* pop();
class iterator;
friend class iterator;
class iterator{
public:
iterator( Stack<T>& tl): _iter(tl._vec.rbegin()),
_iter_end(tl._vec.rend()) {}
iterator( iterator& tl): _iter(tl._iter),
_iter_end(tl._iter_end) {}
iterator() {}
bool operator++(){
_iter++;
if(_iter != _iter_end)
return true;
else
return false;
}
bool operator++(int){
return operator++();
}
T* current() const{
if(_iter == _iter_end)
return 0;
else
return *_iter;
}
T* operator->() const {
require(_iter != _iter_end, "_iter == _iter_end!");
return current();
}
T* operator*() const{
require(_iter != _iter_end, "_iter == _iter_end!");
return current();
}
operator bool() const {
return _iter != _iter_end;
}
bool operator==(const iterator&) const{
return _iter == _iter_end;
}
bool operator!=(const iterator&) const{
return _iter != _iter_end;
}
private:
/*typename vector<T*>::iterator _iter;
typename vector<T*>::iterator _iter_end;*/
typename vector<T*>::reverse_iterator _iter;
typename vector<T*>::reverse_iterator _iter_end;
};
iterator begin() {return iterator(*this);}
iterator end() {return iterator();}
private:
vector<T*> _vec;
};
template<typename T>
Stack<T>::~Stack(){
while(_vec.size() > 0)
delete pop();
}
template<typename T>
T* Stack<T>::pop(){
if(0 == _vec.size())
return 0;
vector<T*>::iterator it = _vec.end();
it--;
T* result = *it;
_vec.erase(it);
return result;
}
#endif //_TSTACK3_H