引入内联函数,可以把Stash和Stack类变得更有效
//: C09:Stash4.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Inline functions
#ifndef STASH4_H
#define STASH4_H
#include "../require.h"
class Stash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
void inflate(int increase);
public:
Stash(int sz) : size(sz), quantity(0),
next(0), storage(0) {}
Stash(int sz, int initQuantity) : size(sz),
quantity(0), next(0), storage(0) {
inflate(initQuantity);
}
Stash::~Stash() {
if(storage != 0)
delete []storage;
}
int add(void* element);
void* fetch(int index) const {
require(0 <= index, "Stash::fetch (-)index");
if(index >= next)
return 0; // To indicate the end
// Produce pointer to desired element:
return &(storage[index * size]);
}
int count() const { return next; }
};
#endif // STASH4_H ///:~
小函数作为内联函数工作是理想的,要注意,两个最大的函数仍旧保留非
内联函数,因为要是把它们作为内联使用的话,很可能性能上得不到改善
//: C09:Stash4.cpp {O}
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
#include "Stash4.h"
#include <iostream>
#include <cassert>
using namespace std;
const int increment = 100;
int Stash::add(void* element) {
if(next >= quantity) // Enough space left?
inflate(increment);
// Copy element into storage,
// starting at next empty space:
int startBytes = next * size;
unsigned char* e = (unsigned char*)element;
for(int i = 0; i < size; i++)
storage[startBytes + i] = e[i];
next++;
return(next - 1); // Index number
}
void Stash::inflate(int increase) {
assert(increase >= 0);
if(increase == 0) return;
int newQuantity = quantity + increase;
int newBytes = newQuantity * size;
int oldBytes = quantity * size;
unsigned char* b = new unsigned char[newBytes];
for(int i = 0; i < oldBytes; i++)
b[i] = storage[i]; // Copy old to new
delete [](storage); // Release old storage
storage = b; // Point to new memory
quantity = newQuantity; // Adjust the size
} ///:~
测试程序表面可以正常运行
//: C09:Stash4Test.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
//{L} Stash4
#include "Stash4.h"
#include "../require.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
Stash intStash(sizeof(int));
for(int i = 0; i < 100; i++)
intStash.add(&i);
for(int j = 0; j < intStash.count(); j++)
cout << "intStash.fetch(" << j << ") = "
<< *(int*)intStash.fetch(j)
<< endl;
const int bufsize = 80;
Stash stringStash(sizeof(char) * bufsize, 100);
ifstream in("Stash4Test.cpp");
assure(in, "Stash4Test.cpp");
string line;
while(getline(in, line))
stringStash.add((char*)line.c_str());
int k = 0;
char* cp;
while((cp = (char*)stringStash.fetch(k++))!=0)
cout << "stringStash.fetch(" << k << ") = "
<< cp << endl;
getchar();
} ///:~
把Stash4Test.cpp 放到 工程目录
输出 正序输出
intStash.fetch(0) = 0
intStash.fetch(1) = 1
intStash.fetch(2) = 2
intStash.fetch(3) = 3
intStash.fetch(4) = 4
intStash.fetch(5) = 5
intStash.fetch(6) = 6
intStash.fetch(7) = 7
intStash.fetch(8) = 8
intStash.fetch(9) = 9
intStash.fetch(10) = 10
intStash.fetch(11) = 11
intStash.fetch(12) = 12
intStash.fetch(13) = 13
intStash.fetch(14) = 14
intStash.fetch(15) = 15
intStash.fetch(16) = 16
intStash.fetch(17) = 17
intStash.fetch(18) = 18
intStash.fetch(19) = 19
intStash.fetch(20) = 20
intStash.fetch(21) = 21
intStash.fetch(22) = 22
intStash.fetch(23) = 23
intStash.fetch(24) = 24
intStash.fetch(25) = 25
intStash.fetch(26) = 26
intStash.fetch(27) = 27
intStash.fetch(28) = 28
intStash.fetch(29) = 29
intStash.fetch(30) = 30
intStash.fetch(31) = 31
intStash.fetch(32) = 32
intStash.fetch(33) = 33
intStash.fetch(34) = 34
intStash.fetch(35) = 35
intStash.fetch(36) = 36
intStash.fetch(37) = 37
intStash.fetch(38) = 38
intStash.fetch(39) = 39
intStash.fetch(40) = 40
intStash.fetch(41) = 41
intStash.fetch(42) = 42
intStash.fetch(43) = 43
intStash.fetch(44) = 44
intStash.fetch(45) = 45
intStash.fetch(46) = 46
intStash.fetch(47) = 47
intStash.fetch(48) = 48
intStash.fetch(49) = 49
intStash.fetch(50) = 50
intStash.fetch(51) = 51
intStash.fetch(52) = 52
intStash.fetch(53) = 53
intStash.fetch(54) = 54
intStash.fetch(55) = 55
intStash.fetch(56) = 56
intStash.fetch(57) = 57
intStash.fetch(58) = 58
intStash.fetch(59) = 59
intStash.fetch(60) = 60
intStash.fetch(61) = 61
intStash.fetch(62) = 62
intStash.fetch(63) = 63
intStash.fetch(64) = 64
intStash.fetch(65) = 65
intStash.fetch(66) = 66
intStash.fetch(67) = 67
intStash.fetch(68) = 68
intStash.fetch(69) = 69
intStash.fetch(70) = 70
intStash.fetch(71) = 71
intStash.fetch(72) = 72
intStash.fetch(73) = 73
intStash.fetch(74) = 74
intStash.fetch(75) = 75
intStash.fetch(76) = 76
intStash.fetch(77) = 77
intStash.fetch(78) = 78
intStash.fetch(79) = 79
intStash.fetch(80) = 80
intStash.fetch(81) = 81
intStash.fetch(82) = 82
intStash.fetch(83) = 83
intStash.fetch(84) = 84
intStash.fetch(85) = 85
intStash.fetch(86) = 86
intStash.fetch(87) = 87
intStash.fetch(88) = 88
intStash.fetch(89) = 89
intStash.fetch(90) = 90
intStash.fetch(91) = 91
intStash.fetch(92) = 92
intStash.fetch(93) = 93
intStash.fetch(94) = 94
intStash.fetch(95) = 95
intStash.fetch(96) = 96
intStash.fetch(97) = 97
intStash.fetch(98) = 98
intStash.fetch(99) = 99
stringStash.fetch(1) = //: C09:Stash4Test.cpp
stringStash.fetch(2) = // From Thinking in C++, 2nd Edition
stringStash.fetch(3) = // Available at http://www.BruceEckel.com
stringStash.fetch(4) = // (c) Bruce Eckel 2000
stringStash.fetch(5) = // Copyright notice in Copyright.txt
stringStash.fetch(6) = //{L} Stash4
stringStash.fetch(7) = #include "Stash4.h"
stringStash.fetch(8) = #include "../require.h"
stringStash.fetch(9) = #include <fstream>
stringStash.fetch(10) = #include <iostream>
stringStash.fetch(11) = #include <string>
stringStash.fetch(12) = using namespace std;
stringStash.fetch(13) =
stringStash.fetch(14) = int main() {
stringStash.fetch(15) = Stash intStash(sizeof(int));
stringStash.fetch(16) = for(int i = 0; i < 100; i++)
stringStash.fetch(17) = intStash.add(&i);
stringStash.fetch(18) = for(int j = 0; j < intStash.count(); j++)
stringStash.fetch(19) = cout << "intStash.fetch(" << j << ") = "
stringStash.fetch(20) = << *(int*)intStash.fetch(j)
stringStash.fetch(21) = << endl;
stringStash.fetch(22) = const int bufsize = 80;
stringStash.fetch(23) = Stash stringStash(sizeof(char) * bufsize, 100);
stringStash.fetch(24) = ifstream in("Stash4Test.cpp");
stringStash.fetch(25) = assure(in, "Stash4Test.cpp");
stringStash.fetch(26) = string line;
stringStash.fetch(27) = while(getline(in, line))
stringStash.fetch(28) = stringStash.add((char*)line.c_str());
stringStash.fetch(29) = int k = 0;
stringStash.fetch(30) = char* cp;
stringStash.fetch(31) = while((cp = (char*)stringStash.fetch(k++))!=0)
stringStash.fetch(32) = cout << "stringStash.fetch(" << k << ") = "
stringStash.fetch(33) = << cp << endl;
stringStash.fetch(34) = } ///:~
Stack类更好地使用了内联函数
//: C09:Stack4.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// With inlines
#ifndef STACK4_H
#define STACK4_H
#include "../require.h"
class Stack {
struct Link {
void* data;
Link* next;
Link(void* dat, Link* nxt):
data(dat), next(nxt) {}
}* head;
public:
Stack() : head(0) {}
~Stack() {
require(head == 0, "Stack not empty");
}
void push(void* dat) {
head = new Link(dat, head);
}
void* peek() const {
return head ? head->data : 0;
}
void* pop() {
if(head == 0) return 0;
void* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}
};
#endif // STACK4_H ///:~
Link析构函数在前面的Stack版本是以空的形式出现的,这里删除了
多数内联函数十分精细和明显,特别对于Link如此
如果所有的函数都是内联函数,那么使用库就会变得相当简单,因为不需要
进行库连接,注意没有Stack4.cpp
//: C09:Stack4Test.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
//{T} Stack4Test.cpp
#include "Stack4.h"
#include "../require.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[]) {
requireArgs(argc, 1); // File name is argument
ifstream in(argv[1]);
assure(in, argv[1]);
Stack textlines;
string line;
// Read file and store lines in the stack:
while(getline(in, line))
textlines.push(new string(line));
// Pop the lines from the stack and print them:
string* s;
while((s = (string*)textlines.pop()) != 0) {
cout << *s << endl;
delete s;
}
getchar();
} ///:~
结果就是按行的逆序输出
有时创建的类都是内联成员函数时,可以把整个类放到头文件中,在程序
开发中,这是有益的,尽管编译时会花费更多的编译时间
输出
命令行参数 Stack4Test.cpp 的绝对路径,字符串要加引号,里面有斜括号
输出
} ///:~
getchar();
}
delete s;
cout << *s << endl;
while((s = (string*)textlines.pop()) != 0) {
string* s;
// Pop the lines from the stack and print them:
textlines.push(new string(line));
while(getline(in, line))
// Read file and store lines in the stack:
string line;
Stack textlines;
assure(in, argv[1]);
ifstream in(argv[1]);
requireArgs(argc, 1); // File name is argument
int main(int argc, char* argv[]) {
using namespace std;
#include <string>
#include <iostream>
#include <fstream>
#include "../require.h"
#include "Stack4.h"
//{T} Stack4Test.cpp
// Copyright notice in Copyright.txt
// (c) Bruce Eckel 2000
// Available at http://www.BruceEckel.com
// From Thinking in C++, 2nd Edition
//: C09:Stack4Test.cpp
本文介绍了一个C++程序中用于管理动态内存的Stash和Stack类。Stash类通过内联函数提高了性能,Stack类则完全由内联函数构成。文章还提供了测试程序,验证了这些类的功能。

284

被折叠的 条评论
为什么被折叠?



