一.相關代碼
1.
/*STACKT.h*/
#ifndef STACKT_H_
#define STACKT_H_
template<class T> class stacktIter;
template<class T>
class stackt
{
enum{ ssize = 100 };
T stack[ssize];
int top;
public:
stackt() : top(0)
{
stack[top] = 0;
}
void push(const T& i)
{
if(top < ssize)
{
stack[top++] = i;
}
}
T pop()
{
return stack[top > 0 ? --top : top];
}
friend class stacktIter<T>;
};
template<class T>
class stacktIter
{
stackt<T>& S;
int index;
public:
stacktIter(stackt<T>& is) : S(is), index(0) {}
T& operator++()
{
if(index < S.top - 1)
{
index++;
}
return S.stack[index];
}
T& operator++(int)
{
int returnval = S.stack[index];
if(index < S.top - 1)
{
index++;
}
return returnval;
}
};
#endif
/*STACKT.cpp*/
#include <assert.h>
#include <iostream.h>
#include "stackt.h"
int fibonacci(int N)
{
const sz = 100;
assert(N < sz);
static F[sz];
F[0] = F[1] = 1;
for(int i = 0; i < sz; ++i)
{
if(F[i] == 0)
{
break;
}
}
while(i <= N)
{
F[i] = F[i-1] + F[i-2];
i++;
}
return F[N];
}
int main()
{
stackt<int> is;
for(int i = 0; i < 20; ++i)
{
is.push(fibonacci(i));
}
stacktIter<int> it(is);
for(int j = 0; j < 20; ++j)
{
cout << it++ << endl;
}
for (int k = 0; k < 20; ++k)
{
cout << is.pop() << endl;
}
return 0;
}
2.
/*TSTASH.h*/
#ifndef TSTASH_H_
#define TSTASH_H_
#include <stdlib.h>
#include "E:\VC++\7_31_2\allege.h"
enum owns{ no = 0, yes = 1, Default};
template<class Type, int sz> class tstashIter;
template<class Type, int chunksize = 20>
class tstash
{
int quantity;
int next;
owns own;//own標誌指明瞭包容器是否以缺省方式擁有它所包容的對象
void inflate(int increase = chunksize);
protected:
Type** storage;
public:
tstash(owns owns = yes);
~tstash();
int Owns() const
{
return own;
}
void Owns(owns newOwns)
{
own = newOwns;
}
int add(Type* element);
int remove(int index, owns d = Default);
Type* operator[](int index);
int count() const
{
return next;
}
friend class tstashIter<Type, chunksize>;
};
template<class Type, int sz = 20>
class tstashIter
{
tstash<Type, sz>& ts;
int index;
public:
tstashIter(tstash<Type, sz>& TS) : ts(TS), index(0) {}
tstashIter(const tstashIter& rv) : ts(rv.ts), index(rv.index) {}
void forward(int amount)
{
index += amount;
if(index >= ts.next)
{
index = ts.next - 1;
}
}
void backward(int amount)
{
index -= amount;
if(index < 0)
{
index = 0;
}
}
int operator++()
{
if(++index >= ts.next)
{
return 0;
}
return 1;
}
int operator++(int)
{
return operator++();
}
int operator--()
{
if(--index < 0)
{
return 0;
}
return 1;
}
int operator--(int)
{
return operator--();
}
operator int()
{
return index >= 0 && index < ts.next;
}
Type* operator->()
{
Type* t = ts.storage[index];
if(t)
{
return t;
}
allege(0, "tstashIter::operator->return 0");
return 0;
}
int remove(owns d = Default)
{
return ts.remove(index, d);
}
};
template<class Type, int sz>
tstash<Type, sz>::tstash(owns Owns) : own(Owns)
{
quantity = 0;
storage = 0;
next = 0;
}
template<class Type, int sz>
tstash<Type, sz>::~tstash()
{
if(!storage)
{
return;
}
if(own == yes)
{
for(int i = 0; i < count(); i++)
{
// delete storage[i];
}
}
free(storage);
}
template<class Type, int sz>
int tstash<Type, sz>::add(Type* element)
{
if(next >= quantity)
{
inflate();
}
storage[next++] = element;
return(next - 1);
}
template<class Type, int sz>
int tstash<Type, sz>::remove(int index, owns d)
{
if(index >= next || index < 0)
{
return 0;
}
switch(d)
{
case Default:
if(own != yes)
{
break;
}
case yes:
delete storage[index];
case no:
storage[index] = 0;
}
return 1;
}
template<class Type, int sz>
Type* tstash<Type, sz>::operator[](int index)
{
assert(index >= 0 && index < next);
return storage[index];
}
template<class Type, int sz>
void tstash<Type, sz>::inflate(int increase)
{
void* v = realloc(storage, (quantity+increase)*sizeof(Type*));
allegemem(v);
storage = (Type**)v;
quantity += increase;
}
#endif
/*創建和檢測兩個不同的 tstash對象,一個屬於新類Int並在它的析構函數和構
造函數中給出報告,而另一個含有屬於第 12章的String類的對象*/
/*TSTEST.cpp*/
#include <fstream.h>
#include "E:\VC++\7_31_2\allege.h"
#include "tstash.h"
#include "E:\VC++\8_4_1\strings.h"
const bufsize = 80;
ofstream out("tstash.out");
class Int
{
int i;
public:
Int(int I = 0) :i(I)
{
out << ">" << i << endl;
}
~Int()
{
out << "~" << i << endl;
}
operator int() const
{
return i;
}
friend ostream&
operator<<(ostream& os, const Int& x)
{
return os << x.i ;
}
};
int main()
{
tstash<Int> intStash;
for(int i = 0; i < 30; ++i)
{
intStash.add(new Int(i));
}
tstashIter<Int> Intit(intStash);
Intit.forward(5);
for(int j = 0; j < 20; ++j, Intit++)
{
Intit.remove();
}
for(int k = 0; k < intStash.count(); ++k)
{
if(intStash[k])
{
out << *intStash[k] << endl;
}
}
ifstream file("tstash.cpp");
allegefile(file);
char buf[bufsize];
tstash<String> stringStash;
while(file.getline(buf, bufsize))
{
stringStash.add(makeString(buf));
}
for(int u = 0; u < stringStash.count(); ++u)
{
if(stringStash[u])
{
out << *stringStash[u] << endl;
}
}
tstashIter<String> it(stringStash);
j = 25;
it.forward(j);
while(it)
{
out << j++ << ": " << it->str() << endl;
it++;
}
return 0;
}
3.
#ifndef TSTACK_H_
#define TSTACK_H_
template<class T> class tstackIterator;
template<class T>
class tstack
{
struct link
{
T* data;
link* next;
link(T* Data, link* Next)
{
data = Data;
next = Next;
}
}*head;
int owns;
public:
tstack(int Owns = 1) : head(0), owns(Owns) {}
~tstack();
void push(T* Data)
{
head = new link(Data, head);
}
T* peek() const
{
return head->data;
}
T* pop();
int Owns() const
{
return owns;
}
void Owns(int newownership)
{
owns = newownership;
}
friend class tstackIterator<T>;
};
template<class T>
T* tstack<T>::pop()
{
if(head == 0)
{
return 0;
}
T* result = head->data;
link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}
template<class T>
tstack<T>::~tstack()
{
link* cursor = head;
while(head)
{
cursor = cursor->next;
if(owns)
{
delete head->data;
}
delete head;
head = cursor;
}
}
template<class T>
class tstackIterator
{
tstack<T>::link* p;
public:
tstackIterator(const tstack<T>& t1)
: p(t1.head) {}
tstackIterator(const tstackIterator& t1)
: p(t1.p) {}
int operator++()
{
if(p->next)
{
p = p->next;
}
else
{
p = 0;
}
return int(p);
}
int operator++(int)
{
return operator++();
}
T* operator->() const
{
if(!p)
{
return 0;
}
return p->data;
}
T* current() const
{
if(!p)
{
return 0;
}
return p->data;
}
operator int() const
//operator int()指出,是否我們已處在表的尾部和是否允許在條件語句中使用該循環子
{
return p ? 1 : 0 ;
}
};
#endif
/*TSTKTST.cpp*/
#include "E:\VC++\8_4_1\strings.h"
#include "E:\VC++\7_31_2\allege.h"
#include "tstack.h"
#include <fstream.h>
int main()
{
ifstream file("tstktst.cpp");
allegefile(file);
const bufsize = 100;
char buf[bufsize];
tstack<String> textlines;
while(file.getline(buf, bufsize))
{
textlines.push(String::make(buf));
}
int i = 0;
tstackIterator<String> it(textlines);
tstackIterator<String>* it2 = 0;
while(it)
{
cout << *it.current() << endl;
it++;
if(++i == 10)
{
it2 = new tstackIterator<String>(it);
}
}
cout << *(it2->current()) << endl;
delete it2;
return 0;
}
4.
/*SSTRING.h*/
#ifndef SSTRING_H_
#define SSTRING_H_
#include <string.h>
#include <iostream.h>
template<int bsz = 0>
class SString
{
char buf[bsz + 1];
char* s;
public:
SString(const char* S = "") : s(buf)
{
if(!bsz)
{
s = new char[strlen(S) + 1];
strcpy(s, S);
}
else
{
buf[bsz] = 0;
strncpy(s, S, bsz);
}
}
SString(const SString& rv) : s(buf)
{
if(!bsz)
{
s = new char[strlen(rv.s) + 1];
strcpy(s, rv.s);
}
else
{
buf[bsz] = 0;
strncpy(s, rv.s, bsz);
}
}
SString& operator=(const SString& rv)
{
if(&rv == this)
{
return *this;
}
if(!bsz)
{
delete s;
s = new char[strlen(rv.s) + 1];
}
strcpy(s, rv.s);
return *this;
}
~SString()
{
if(!bsz)
{
delete []s;
}
}
int operator==(const SString& rv) const
{
return !stricmp(s, rv.s);
//字符串的比較運算符
}
int operator!=(const SString& rv) const
{
return stricmp(s, rv.s);
}
int operator>(const SString& rv) const
{
return stricmp(s, rv.s) > 0;
}
int operator<(const SString& rv) const
{
return stricmp(s, rv.s) < 0;
}
char* str() const
{
return s;
}
friend ostream&
operator<<(ostream& os,
const SString<bsz>& S)
{
return os << S.s;
}
};
typedef SString<> Hstring;
//通過使用typedef Hstring,我們可以得到一個普通的基於堆的字符串(使用typedef而不是
//使用繼承是因爲繼承需要重新創建構造函數和重載符 =)。
#endif
5.
/*INTEGER.cpp*/
#ifndef INREGER_H_
#define INTEGER_H_
#include <iostream.h>
class integer
{
int i;
public:
integer(int ii = 0) : i(ii) {}
operator int() const
{
return i;
}
const integer& operator++()
{
i++;
return *this;
}
const integer operator++(int)
{
integer returnval(i);
i++;
return returnval;
}
integer& operator+=(const integer& x)
{
i += x.i;
return *this;
}
friend ostream&
operator<<(ostream& os, const integer& x)
{
return os << x.i;
}
};
#endif
6.
/*“無窮”向量
下面的向量類僅僅擁有指針。它從不需要調整大小:我們可以簡單地對任何位置進行索引,
這些位置可魔術般地變化,而無需提前通知向量類。 operator[]能返回一個指針的引用,所以可
以出現在=的左邊(它可以是一個左值,也可以是一個右值)。向量類僅僅與指針打交道,所以
它工作的對象沒有類型限制,對於類型的行爲沒有事先假定的必要。*/
/*VECTOR.cpp*/
#ifndef VECTOR_H_
#define VECTOR_H_
#include <stdlib.h>
#include "E:\VC++\7_31_2\allege.h"
template<class T>
class vector
{
T** pos;
int pos_sz;
T** neg;
int neg_sz;
int owns;
enum
{
chunk = 20,
esz = sizeof(T*),
};
void expand(T**& array, int& size, int index);
public:
vector(int Owns = 1);
~vector();
T*& operator[](int index);
int Owns() const
{
return owns;
}
void Owns(int newOwns)
{
owns = newOwns;
}
};
template<class T>
vector<T>::vector(int Owns)
: pos(0), pos_sz(0),
neg(0), neg_sz(0),
owns(Owns){}
template<class T>
vector<T>::~vector()
{
if(owns)
{
for(int i = 0; i < pos_sz; ++i)
{
delete pos[i];
}
}
free(pos);
if(owns)
{
for(int j = 0; j < neg_sz; ++j)
{
delete neg[j];
}
}
free(neg);
}
template<class T>
T*& vector<T>::operator[](int index)
{
if(index < 0)
{
index *= -1;
if(index >= neg_sz)
{
expand(neg, neg_sz, index);
}
return neg[index];
}
else
{
if(index >= pos_sz)
{
expand(pos, pos_sz, index);
}
return pos[index];
}
}
template<class T> void
vector<T>::expand(T**& array, int& size,
int index)
//expand()採用的參數是引用T**&而不是一個指針
{
const newsize = index +chunk;
const increment = newsize - size;
void* v = realloc(array, newsize * esz);
allegemem(v);
array = (T**)v;
memset(&array[size], 0, increment * esz);
size = index + chunk;
}
#endif;
/*VECTOR.cpp*/
#include <fstream.h>
#include "E:\VC++\7_31_2\allege.h"
#include "vector.h"
#include "E:\VC++\8_7_4\sstring.h"
typedef SString<40> String;
int main()
{
ifstream source("vector.cpp");
allegefile(source);
const bsz = 255;
char buf[bsz];
vector<String> words;
int i = 0;
while(source.getline(buf, bsz))
{
char* s = strtok(buf, "\t");
//標準C函數strtok(),它取字符緩衝區的起始地址(第一個參數)和尋找定界符(第二個參數)
while(s)
{
words[i++] = new String(s);
s = strtok(0, "\t");
}
words[i++] = new String("\n");
}
for(int j = 0; words[j]; ++j)
{
cout << *words[j] << ' ';
}
}
7.
/*SET.cpp*/
#ifndef SET_H_
#define SET_H_
#include "E:\VC++\8_7_6\vector.h"
#include <assert.h>
template<class Type>
class set
{
vector<Type> elem;
int max;
int lastindex;
int within(const Type& e)
{
for(lastindex = 0; lastindex < max; ++lastindex)
{
if(elem[lastindex]->operator == (e))
{
return lastindex;
}
}
return -1;
}
void operator=(set&);
set(set&);
public:
set() : max(0), lastindex(0) {}
void add(const Type&);
int contains(const Type&);
int index(const Type& e);
Type& operator[] (int index)
{
assert(index >= 0 && index < max);
return *elem[index];
}
int length() const
//length()告訴我們集合中有多少個元素
{
return max;
}
};
template<class Type> void
set<Type>::add(const Type& e)
//add()在檢測確定一個新元素不在集合後,將其追加入集合中
{
if(!contains(e))
{
elem[max] = new Type(e);
max++;
}
}
template<class Type> int
set<Type>::contains(const Type& e)
//contains()告訴我們對象是否已存在於集合之中
{
return within(e) != -1;
}
template<class Type> int
set<Type>::index(const Type& e)
//index()告訴我們對象在集合之中的位置
{
if(elem[lastindex]->operator != (e))
{
int ind = within(e);
assert(ind != -1);
}
return lastindex;
}
#endif
/*SETTEST.cpp*/
#include <fstream.h>
#include "set.h"
#include "E:\VC++\7_31_2\allege.h"
#include "E:\VC++\8_7_4\sstring.h"
const char* delimiters =
" \t;()\''<>:{}[]+-=&*#.,/\\"
"0123456789";
typedef SString<40> String;
int main(int argc, char* argv[])
{
allege(argc == 2, "need file argument");
ifstream in(argv[1]);
allegefile(in);
ofstream out("settest.out");
set<String> concordance;
const sz = 255;
char buf[sz];
while(in.getline(buf, sz))
{
char* s = strtok(buf, delimiters);//定界符
while(s)
{
concordance.add(s);
s = strtok(0, delimiters);
}
}
for(int i = 0; i < concordance.length(); ++i)
{
out << concordance[i] << endl;
}
return 0;
}
8.
/*ASSOC.h*/
#ifndef ASSOC_H_
#define ASSOC_H_
#include "E:\VC++\8_7_7\set.h"
#include <assert.h>
template<class In, class Out>
class assoc_array
{
set<In> inVal;
vector<Out> outVal;
int max;
void operator=(assoc_array&);
assoc_array(assoc_array&);
public:
assoc_array() : max(0) {}
Out& operator[] (const In&);
int length() const
{
return max;
}
In& in_value(int i)
{
assert(i >= 0 && i < max);
return inVal[i];
}
Out& out_value(int i)
{
assert(i >= 0 && i < max);
return *outVal[i];
}
};
template<class In, class Out> Out&
assoc_array<In,Out>::operator[](const In& in)
{
if(!inVal.contains(in))
{
inVal.add(in);
outVal[max] = new Out;
max++;
}
int x = inVal.index(in);
return *outVal[inVal.index(in)];
}
#endif
/*ASSOC.cpp*/
#include "assoc.h"
#include "E:\VC++\8_7_4\sstring.h"
#include "E:\VC++\8_7_5\integer.h"
#include "E:\VC++\7_31_2\allege.h"
#include <fstream.h>
#include <ctype.h>
int main()
{
const char* delimiters =
"\t;()\''<>;{}[]+-=&*#.,/\\";
assoc_array<SString<80>, integer> strcount;
ifstream source("assoc.cpp");
allegefile(source);
ofstream out("assoc.out");
allegefile(out);
const bsz = 255;
char buf[bsz];
while(source.getline(buf, bsz))
{
char* s = strtok(buf, delimiters);
while(s)
{
strcount[s]++;
s = strtok(0, delimiters);
}
}
for(int i = 0; i < strcount.length(); ++i)
{
out << strcount.in_value(i) << " : "
<< strcount.out_value(i) << endl;
}
assoc_array<SString<>, integer> shoplist;
ifstream list("shoplist.txt");
allegefile(list);
ofstream olist("shoplist.out");
allegefile(olist);
while(list.getline(buf, bsz))
{
int i = strlen(buf) - 1;
while(isspace(buf[i]))
{
i--;
}
while(!isspace(buf[i]))
{
i--;
}
int count = atoi(&buf[i+1]);
while(isspace(buf[i]))
{
i--;
}
buf[i+1] = 0;
i = 0;
while(isspace(buf[i]))
{
i++;
}
shoplist[&buf[i]] += count;
}
for(int j = 0; j < shoplist.length(); ++j)
{
olist << shoplist.in_value(j) << " : "
<< shoplist.out_value(j) << endl;
}
return 0;
}
9.
/*SORTED.h*/
#ifndef SORTED_H_
#define SORTED_H_
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "E:\VC++\8_7_2\tstash.h"
#include "E:\VC++\8_7_7\set.h"
template<class T>
class sorted : public tstash<T>
{
void bubblesort();
public:
int add(T* element)
{
tstash<T>::add(element);
bubblesort();
return 0;
}
};
template<class T>
void sorted<T>::bubblesort()
{
for(int i = count(); i > 0; --i)
{
for(int j = 1; j > i; ++j)
{
if(*storage[j - 1] > *storage[j])
{
T* t = storage[j - 1];
storage[j - 1] = storage[j];
storage[j] = t;
}
}
}
}
template<class T>
class sortedSet : public set<T>
{
sorted<T> Sorted;
public:
void add(T& e)
{
if(contains(e))
{
return;
}
set<T>::add(e);
Sorted.add(new T(e));
}
T& operator[] (int index)
{
assert(index >= 0 && index < length());
assert(Sorted[index]);
return *Sorted[index];
}
int length()
{
return Sorted.count();
}
};
template<int upper_bound>
class urand
{
int map[upper_bound];
int recycle;
public:
urand(int Recycle = 0);
int operator()();
};
template<int upper_bound>
urand<upper_bound>::urand(int Recycle)
: recycle(Recycle)
{
memset(map, 0, upper_bound * sizeof(int));
time_t t;
srand((unsigned)time(&t));
}
template<int upper_bound>
int urand<upper_bound>::operator()()
{
if(!memchr(map, 0, upper_bound))
{
if(recycle)
{
memset(map, 0, sizeof(map) * sizeof(int));
}
else
{
return -1;
}
}
int newval;
while(map[newval = rand() % upper_bound]);
map[newval]++;
return newval;
}
#endif
/*SORTED.cpp*/
#include "sorted.h"
#include "E:\VC++\8_7_5\integer.h"
#include "E:\VC++\8_7_4\sstring.h"
typedef SString<40> String;
char* words[] =
{
"is", "running", "big", "dog", "a",
};
const wordsz = sizeof words / sizeof *words;
int main()
{
sorted<String> ss;
for(int i = 0; i < wordsz; ++i)
{
ss.add(new String(words[i]));
}
for(int j = 0; j < ss.count(); ++j)
{
cout << ss[j]->str() << endl;
}
sorted<integer> is;
urand<47> rand1;
for(int k = 0; k < 15; ++k)
{
is.add(new integer(rand1()));
}
for(int l = 0; l < is.count(); ++l)
{
cout << *is[l] << endl;
}
return 0;
}
10.
/*NOBLOAT.h*/
#ifndef NOBLOAT_H_
#define NOBLOAT_H_
#include "E:\VC++\8_4_3\stackl1.h"
template<class T>
class nbstack : public stack
{
public:
void push(T* str)
{
stack::push(str);
}
T* peek() const
{
return (T*)stack::peek();
}
T* pop()
{
return (T*)stack::pop();
}
~nbstack();
};
template<class T>
nbstack<T>::~nbstack()
{
T* top = pop();
while(top)
{
delete top;
top = pop();
}
}
#endif
11.
/*GETMEM.h*/
#ifndef GETMEM_H_
#define GETMEM_H_
#include <stdlib.h>
#include <string.h>
#include "E:\VC++\7_31_2\allege.h"
template<class T>
void getmem(T*& oldmem, int elems)
{
typedef int cntr;
const int csz = sizeof(cntr);
const int Tsz = sizeof(T);
if(elems == 0)
{
free(&(((cntr*)oldmem)[-1]));
return;
}
T* p = oldmem;
cntr oldcount = 0;
if(p)
{
(cntr*)p--;
oldcount = *(cntr*)p;
}
T* m = (T*)realloc(p, elems*Tsz + csz);
allegemem(m);
*((cntr*)m) = elems;
const cntr increment = elems - oldcount;
if(increment > 0)
{
long startadr = (long)&(m[oldcount]);
startadr += csz;
memset((void*)startadr, 0, increment*Tsz);
}
oldmem = (T*)&(((cntr*)m)[1]);
}
template<class T>
inline void freemem(T * m)
{
getmem(m, 0);
}
#endif
</pre><pre name="code" class="cpp">/*GETMEM.cpp*/
#include "getmem.h"
#include <iostream.h>
int main()
{
int* p = 0;
getmem(p, 10);
for(int i = 0; i < 10; ++i)
{
cout << p[i] << ' ';
p[i] = i;
}
cout << '\n';
getmem(p, 20);
for(int j = 0; j < 20; ++j)
{
cout << p[j] << ' ';
p[j] = j;
}
cout << '\n';
getmem(p, 25);
for(int k = 0; k ,25; ++k)
{
cout << p[k] << ' ';
}
freemem(p);
cout << '\n';
float* f = 0;
getmem(f, 3);
for(int u = 0; u < 3 ;++u)
{
cout << f[u] << ' ';
f[u] = u + 3.14159;
}
cout << '\n';
getmem(f, 6);
for(int v = 0; v < 6; ++v)
{
cout << f[v] << ' ';
}
freemem(f);
return 0;
}
12.
/*ISTACK.cpp*/
#include <iostream.h>
#include <assert.h>
class istack
{
enum{ ssize = 100 };
int stack[ssize];
int top;
public:
istack() : top(0)
{
stack[top] = 0;
}
void push(int i)
{
if(top < ssize)
{
stack[top++] = i;
}
}
int pop()
{
return stack[top > 0 ? --top : top];
}
friend class istackIter;
};
class istackIter
{
istack& S;
int index;
public:
istackIter(istack& is) : S(is), index(0) {}
int operator++()
{
if(index < S.top - 1)
{
index++;
}
return S.stack[index];
}
int operator++(int)
{
int returnval = S.stack[index];
if(index < S.top - 1)
{
index++;
}
return returnval;
}
};
int fibonacci(int N)
{
const sz = 100;
assert(N < sz);
static F[sz];
F[0] = F[1] = 1;
for(int i = 0; i < sz; ++i)
{
if(F[i] == 0)
{
break;
}
}
while(i <= N)
{
F[i] = F[i-1] + F[i-2];
i++;
}
return F[N];
}
int main()
{
istack is;
for(int i = 0; i < 20; ++i)
{
is.push(fibonacci(i));
}
istackIter it(is);
for(int j = 0; j < 20; ++j)
{
cout << it++ << endl;
}
for (int k = 0; k < 20; ++k)
{
cout << is.pop() << endl;
}
return 0;
}
13.
/*模板語法*/
/*STEMP.cpp*/
#include <iostream.h>
#include <assert.h>
template<class T>
class array
{
enum{ size = 100 };
T A[size];
public:
T& operator[](int index)
{
assert(index >= 0 && index < size);
return A[index];
}
};
int main()
{
array<int> ia;
array<float> fa;
for(int i = 0; i < 20; ++i)
{
ia[i] = i * i;
fa[i] = float(i) * 1.414;
}
for(int j = 0; j < 20; ++j)
{
cout << j << ": " << ia[j]
<< ", " << fa[j] << endl;
}
return 0;
}
14.
/*說明非內聯成員函數的定義*/
/*STEMP2.cpp*/
#include <iostream.h>
#include <assert.h>
template<class T>
class array
{
enum{ size = 100 };
T A[size];
public:
T& operator[](int index);
};
template<class T>
T& array<T>::operator[](int index)
{
assert(index >= 0 && index < size);
return A[index];
}
int main()
{
array<float> fa;
fa[0] = 1.414;
return 0;
}
15.
/*模板中的常量
模板參數並不侷限於有類定義的類型,可以使用編譯器內置類型。這些參數值在模板特定
實例時變成編譯期間常量。我們甚至可以對這些參數使用缺省值*/
/*MBLOCK.cpp*/
/*類holder和mblock極爲相似,但是在 holder中有一個指向mblock的指針,而不是含有
mblock類型的嵌入式對象。該指針並不在 holder的構造函數中初始化,其初始化過程被安排在
第一次訪問的時候。 如果我們正在創建大量的對象,卻又不立即全部訪問它們,可以用這種
技術,以節省存儲空間。*/
#include <assert.h>
#include <iostream.h>
template<class T, int size = 100>
class mblock
{
T array[size];
public:
T& operator[](int index)
{
assert(index >= 0 && index < size);
return array[index];
}
};
class number
{
float f;
public:
number(float F = 0.0f) : f(F) {}
number& operator=(const number& n)
{
f = n.f;
return *this;
}
operator float() const
{
return f;
}
friend ostream&
operator<<(ostream& os, const number& x)
{
return os << x.f;
}
};
template<class T, int sz = 20>
class holder
{
mblock<T, sz>* np;
public:
holder() : np(0) {}
number& operator[](int i)
{
assert(i >= 0 && i < sz);
if(!np)
{
np = new mblock<T, sz>;
}
return np->operator[](i);
}
};
int main()
{
holder<number, 20> H;
for(int i = 0; i < 20; ++i)
{
H[i] = i;
}
for(int j = 0; j < 20; ++j)
{
cout << H[j] << endl;
}
return 0;
}
16.
/*垃圾回收模擬*/
/*RECYCLE.cpp*/
#include <fstream.h>
#include <stdlib.h>
#include <time.h>
#include "E:\VC++\8_7_3\tstack.h"
ofstream out("recycle.out");
enum type{ Aluminum, Paper, Glass };
class trash
{
float Weight;
public:
trash(float Wt) : Weight(Wt) {}
virtual type trashType() const = 0;
virtual const char* name() const = 0;
virtual float value() const = 0;
float weight() const
{
return Weight;
}
virtual ~trash() {}
};
class aluminum : public trash
{
static float val;
public:
aluminum(float Wt) : trash(Wt) {}
type trashType() const
{
return Aluminum;
}
virtual const char* name() const
{
return "aluminum";
}
float value() const
{
return val;
}
static void value(int newval)
{
val = newval;
}
};
float aluminum::val = 1.67;
class paper : public trash
{
static float val;
public:
paper(float Wt) : trash(Wt) {}
type trashType() const
{
return Paper;
}
virtual const char* name() const
{
return "paper";
}
float value() const
{
return val;
}
static void value(int newval)
{
val = newval;
}
};
float paper::val = 0.10;
class glass : public trash
{
static float val;
public:
glass(float Wt) : trash(Wt) {}
type trashType() const
{
return Glass;
}
virtual const char* name() const
{
return "glass";
}
float value() const
{
return val;
}
static void value(int newval)
{
val = newval;
}
};
float glass::val = 0.23;
void SumValue(const tstack<trash>& bin, ostream& os)
{
tstackIterator<trash> tally(bin);
float val = 0;
while(tally)
{
val += tally->weight() * tally->value();
os << "weight of" << tally->name()
<< " = " << tally->weight() << endl;
tally++;
}
os << "Total value = " << val << endl;
}
int main()
{
time_t t;
srand((unsigned)time(&t));
tstack<trash> bin;
for(int i = 0; i < 30; ++i)
{
switch(rand() % 3)
{
case 0:
bin.push(new aluminum(rand() % 100));
break;
case 1:
bin.push(new paper(rand() % 100));
break;
case 2:
bin.push(new glass(rand() % 100));
break;
}
}
tstack<trash> glassbin(0);
tstack<trash> paperbin(0);
tstack<trash> ALbin(0);
tstackIterator<trash> sorter(bin);
while(sorter)
{
switch(sorter->trashType())
{
case Aluminum:
ALbin.push(sorter.current());
break;
case Paper:
paperbin.push(sorter.current());
break;
case Glass:
glassbin.push(sorter.current());
break;
}
sorter++;
}
SumValue(ALbin, out);
SumValue(paperbin, out);
SumValue(glassbin, out);
SumValue(bin, out);
return 0;
}
17.
/*APPLIST.cpp*/
#include "E:\VC++\8_7_3\tstack.h"
#include <iostream.h>
template<class T, class R>
void applist(tstack<T>& t1, R(T::*f)())
{
tstackIterator<T> it(t1);
while(it)
{
(it.current()->*f)();
it++;
}
}
template<class T, class R, class A>
void applist(tstack<T>& t1, R(T::*f)(A), A a)
{
tstackIterator<T> it(t1);
while(it)
{
(it.current()->*f)(a);
it++;
}
}
template<class T , class R, class A1, class A2>
void applist(tstack<T>& t1, R(T::*f)(A1, A2),
A1 a1, A2 a2)
{
tstackIterator<T> it(t1);
while(it)
{
(it.current()->*f)(a1, a2);
it++;
}
}
class gromit
{
int arf;
public:
gromit(int Arf = 1) : arf(Arf+1) {}
void speak(int)
{
for(int i = 0; i < arf; ++i)
{
cout << "arf!";
}
cout << endl;
}
char eat(float)
{
cout << "chomp!" << endl;
return 'z';
}
int sleep(char, double)
{
cout << "zzz..." << endl;
return 0;
}
void sit(void) {}
};
int main()
{
tstack<gromit> dogs;
for(int i = 0; i < 5; ++i)
{
dogs.push(new gromit(i));
}
applist(dogs, &gromit::speak, 1);
applist(dogs, &gromit::eat, 2.0f);
applist(dogs, &gromit::sleep, 'z', 3.0);
applist(dogs, &gromit::sit);
//dogs.applist(&gromit::sit);
return 0;
}
18.
/*GENERATE.cpp*/
#include "E:\VC++\8_7_9\sorted.h"
#include "E:\VC++\8_7_5\integer.h"
template class sorted<integer>;
int main()
{
sorted<integer> is;
urand<47> rand1;
for(int k = 0; k < 15; ++k)
{
is.add(new integer(rand1()));
}
for(int l = 0; l < is.count(); ++l)
{
cout << *is[l] << endl;
}
return 0;
}
19.
/*SPECIAL.cpp*/
#include "E:\VC++\8_7_9\sorted.h"
#include <iostream.h>
class sorted<char> : public tstash<char>
{
void bubblesort();
public:
int add(char* element)
{
tstash<char>::add(element);
bubblesort();
return 0;
}
};
void sorted<char>::bubblesort()
{
for(int i = count(); i > 0;--i)
{
for(int j = 1; j < i; ++j)
{
if(strcmp(storage[j], storage[j-1]) < 0)
{
char* t = storage[j-1];
storage[j-1] = storage[j];
storage[j] = t;
}
}
}
}
char* words[] =
{
"is", "running", "big", "dog", "a",
};
const wsz = sizeof words/sizeof *words;
void main()
{
sorted<char> sc;
for(int k = 0; k < wsz; ++k)
{
sc.add(words[k]);
}
for(int l = 0; l < sc.count(); ++l)
{
cout << sc[l] << endl;
}
}
二.習題+解答
1. 修改第1 4章練習一的結果,以便使用 tstack 和 tstackIterator替代 shape指針數組。增加針對類層次的析構函數以便在 tstack超出範圍時觀察shape對象被析構。
2. 修改第1 4章例子SSHAPE2.CPP以使用tstack替代數組。
3. 修改RECYCLE.CPP以使用tstash替代tstack。
4. 改變SETTEST.CPP以使用sortedSet替代set。
5. 爲 tstash 類複製A P P L I S T. C P P的功能。
6. 將T S TA C K . H拷貝到新的頭文件中,並增加 A P P L I S T. C P P中的函數模板作爲 t s t a c k的成
員函數模板。本練習要求我們的編譯器支持成員函數模板。
7. (高級)修改t s t a c k類以促進增加所有權的區分粒度。爲每一個鏈接增加標誌以表明它
是否擁有其指向的對象,並在 a d d ( )函數和析構函數中支持這一標誌信息。增加用於讀取和改
變每一鏈接所有權的成員函數,並在新的上下文環境中確定 a d d ( )標誌的含義。
8. (高級)修改t s t a c k類,使每一個入口包含引用計數信息(不是它們所包容的對象)並且
增加用於支持引用計數行爲的成員函數。
9. (高級)改變S O RT E D . C P P中u r a n d的底層實現以提高其空間效率( S O RT E D . C P P後面段
落所描述的) 而非時間效率。
10. (高級)將G E T M E M . H中的typedef cntr從整型改成長整型,並且修改代碼以消除失去
精度的警示信息,這是一個指針算術問題。
11. (高級)設計一個測試程序,用於比較創建在堆上和創建在棧上的 S S t r i n g的執行速度。