- 论坛徽章:
- 0
|
Stash的结构为:
//Stash.h
#ifndef STASH_H
#define STASH_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 size);
~Stash();
int add(void* element);
void* fetch(int index);
int count();
};
#endif // STASH_H ///:~
原本Stash的实现为:
//Stash.cpp
#include "Stash2.h"
#include "../require.h"
#include <iostream>;
#include <cassert>;
using namespace std;
const int increment = 100;
Stash::Stash(int sz) {
size = sz;
quantity = 0;
storage = 0;
next = 0;
}
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;
next++;
return(next - 1); // Index number
}
void* Stash::fetch(int index) {
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 Stash::count() {
return next; // Number of elements in CStash
}
void Stash::inflate(int increase) {
require(increase >; 0,
"Stash::inflate zero or negative increase" ;
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 = storage; // Copy old to new
delete [](storage); // Old storage
storage = b; // Point to new memory
quantity = newQuantity;
}
Stash::~Stash() {
if(storage != 0) {
cout << "freeing storage" << endl;
delete []storage;
}
} ///:~
现在我编了个内存分配和管理的程序:
//Mem.h
#ifndef MEM_H
#define MEM_H
typedef unsigned char byte;
class Mem
{
byte* mem;
int size;
void ensureMinSize(int minSize);
public:
Mem();
Mem(int sz);
~Mem();
int msize();
byte* pointer();
byte* pointer(int minSize);
};
#endif
//Mem.cpp
#include "Mem.h"
#include <cstring>;
//using namespace std;
Mem::Mem() { mem = 0; size = 0; }
Mem::Mem(int sz)
{
mem = 0;
size = 0;
ensureMinSize(sz);
}
Mem::~Mem() { delete []mem; }
int Mem::msize() { return size; }
void Mem::ensureMinSize(int minSize)
{
if(size < minSize)
{
byte* newmem = new byte[minSize];
memset(newmem + size,0,minSize - size);
memcpy(newmem,mem,size);
delete []mem;
mem = newmem;
size = minSize;
}
}
byte* Mem::pointer() { return mem; }
byte* Mem::pointer(int minSize)
{
ensureMinSize(minSize);
return mem;
}
现在如何用Mem来实现Stash?
其中的require.h文件如下:
//: :require.h
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Test for error conditions in programs
// Local "using namespace std" for old compilers
#ifndef REQUIRE_H
#define REQUIRE_H
#include <cstdio>;
#include <cstdlib>;
#include <fstream>;
#include <string>;
inline void require(bool requirement,
const std::string& msg = "Requirement failed" {
using namespace std;
if (!requirement) {
fputs(msg.c_str(), stderr);
fputs("\n", stderr);
exit(1);
}
}
inline void requireArgs(int argc, int args,
const std::string& msg =
"Must use %d arguments" {
using namespace std;
if (argc != args + 1) {
fprintf(stderr, msg.c_str(), args);
fputs("\n", stderr);
exit(1);
}
}
inline void requireMinArgs(int argc, int minArgs,
const std::string& msg =
"Must use at least %d arguments" {
using namespace std;
if(argc < minArgs + 1) {
fprintf(stderr, msg.c_str(), minArgs);
fputs("\n", stderr);
exit(1);
}
}
inline void assure(std::ifstream& in,
const std::string& filename = "" {
using namespace std;
if(!in) {
fprintf(stderr, "Could not open file %s\n",
filename.c_str());
exit(1);
}
}
inline void assure(std: fstream& out,
const std::string& filename = "" {
using namespace std;
if(!out) {
fprintf(stderr, "Could not open file %s\n",
filename.c_str());
exit(1);
}
}
#endif // REQUIRE_H ///:~ |
|