读书人

泛型编程下的一个有关问题

发布时间: 2012-09-24 13:49:41 作者: rapoo

泛型编程上的一个问题
#ifndef _GC_H_
#define _GC_H_
#include <iostream>
#include <list>
#include <typeinfo>
#include <cstdlib>

using namespace std;
class OutOfRangeExc {
// Add functionality if needed by your application.
};

template <class T> class Iter {
T *ptr; // current pointer value
T *end; // points to element one past end
T *begin; // points to start of allocated array
unsigned length; // length of sequence
public:

Iter() {
ptr = end = begin = NULL;
length = 0;
}

Iter(T *p, T *first, T *last) {
ptr = p;
end = last;
begin = first;
length = last - first;
}

.
unsigned size() { return length; }

T &operator*() {
if( (ptr >= end) || (ptr < begin) )
throw OutOfRangeExc();
return *ptr;
}

T *operator->() {
if( (ptr >= end) || (ptr < begin) )
throw OutOfRangeExc();
return ptr;
}

Iter operator++() {
ptr++;
return *this;
}

Iter operator--() {
ptr--;
return *this;
}

Iter operator++(int notused) {
T *tmp = ptr;

ptr++;
return Iter<T>(tmp, begin, end);
}

Iter operator--(int notused) {
T *tmp = ptr;

ptr--;
return Iter<T>(tmp, begin, end);
}

T &operator[](int i) {
if( (i < 0) || (i >= (end-begin)) )
throw OutOfRangeExc();
return ptr[i];
}

bool operator==(Iter op2) {
return ptr == op2.ptr;
}

bool operator!=(Iter op2) {
return ptr != op2.ptr;
}

bool operator<(Iter op2) {
return ptr < op2.ptr;
}

bool operator<=(Iter op2) {
return ptr <= op2.ptr;
}

bool operator>(Iter op2) {
return ptr > op2.ptr;
}

bool operator>=(Iter op2) {
return ptr >= op2.ptr;
}

Iter operator-(int n) {
ptr -= n;
return *this;
}

Iter operator+(int n) {
ptr += n;
return *this;
}

int operator-(Iter<T> &itr2) {
return ptr - itr2.ptr;
}

};

template <class T> class GCInfo {
public:
unsigned refcount; // current reference count

T *memPtr; // pointer to allocated memory

/* isArray is true if memPtr points
to an allocated array. It is false
otherwise. */
bool isArray; // true if pointing to array

/* If memPtr is pointing to an allocated
array, then arraySize contains its size */
unsigned arraySize; // size of array

GCInfo(T *mPtr, unsigned size=0) {
refcount = 1;
memPtr = mPtr;
if(size != 0)
isArray = true;
else
isArray = false;

arraySize = size;
}
};

template <class T> bool operator==(const GCInfo<T> &ob1,
const GCInfo<T> &ob2) {
return (ob1.memPtr == ob2.memPtr);
}

template <class T, int size=0> class GCPtr {



// gclist maintains the garbage collection list.
static list<GCInfo<T> > gclist;

// addr points to the allocated memory to which
// this GCPtr pointer currently points.
T *addr;

/* isArray is true if this GCPtr points
to an allocated array. It is false
otherwise. */
bool isArray; // true if pointing to array

// If this GCPtr is pointing to an allocated
// array, then arraySize contains its size.
unsigned arraySize; // size of the array

static bool first; // true when first GCPtr is created

// Return an interator to pointer info in gclist.
typename list<GCInfo<T> >::iterator findPtrInfo(T *ptr);

public:

// Define an iterator type for GCPtr<T>.
typedef Iter<T> GCiterator;

// Construct both initialized and uninitialized objects.
GCPtr(T *t=NULL) {

// Register shutdown() as an exit function.
if(first) atexit(shutdown);
first = false;
list<GCInfo<T> >::iterator p;

p = findPtrInfo(t);

if(p != gclist.end())
p->refcount++; // increment ref count
else {
// Create and store this entry.
GCInfo<T> gcObj(t, size);
gclist.push_front(gcObj);
}

addr = t;
arraySize = size;
if(size > 0) isArray = true;
else isArray = false;
#ifdef DISPLAY
cout << "Constructing GCPtr. ";
if(isArray)
cout << " Size is " << arraySize << endl;
else
cout << endl;
#endif
}

GCPtr(const GCPtr &ob) {
list<GCInfo<T> >::iterator p;

p = findPtrInfo(ob.addr);
p->refcount++; // increment ref count

addr = ob.addr;
arraySize = ob.arraySize;
if(arraySize > 0) isArray = true;
else isArray = false;
#ifdef DISPLAY
cout << "Constructing copy.";
if(isArray)
cout << " Size is " << arraySize << endl;
else
cout << endl;
#endif
}

~GCPtr();

static bool collect();

// Overload assignment of pointer to GCPtr.
T *operator=(T *t);

// Overload assignment of GCPtr to GCPtr.
GCPtr &operator=(GCPtr &rv);


T &operator*() {
return *addr;
}


T *operator->() { return addr; }

T &operator[](int i) {
return addr[i];
}

// Conversion function to T *.
operator T *() { return addr; }

// Return an Iter to the start of the allocated memory.
Iter<T> begin() {
int size;

if(isArray) size = arraySize;
else size = 1;

return Iter<T>(addr, addr, addr + size);
}

// Return an Iter to one past the end of an allocated array.
Iter<T> end() {
int size;

if(isArray) size = arraySize;
else size = 1;

return Iter<T>(addr + size, addr, addr + size);
}


static int gclistSize() { return gclist.size(); }



static void showlist();

static void shutdown();
};

template <class T, int size>
list<GCInfo<T> > GCPtr<T, size>::gclist;

template <class T, int size>
bool GCPtr<T, size>::first = true;

template <class T, int size>
GCPtr<T, size>::~GCPtr() {
list<GCInfo<T> >::iterator p;

p = findPtrInfo(addr);
if(p->refcount) p->refcount--; // decrement ref count

#ifdef DISPLAY
cout << "GCPtr going out of scope.\n";
#endif


collect();

}

template <class T, int size>
bool GCPtr<T, size>::collect() {
bool memfreed = false;

#ifdef DISPLAY
cout << "Before garbage collection for ";
showlist();
#endif

list<GCInfo<T> >::iterator p;
do {

for(p = gclist.begin(); p != gclist.end(); p++) {
if(p->refcount > 0) continue;

memfreed = true;

gclist.remove(*p);

if(p->memPtr) {
if(p->isArray) {
#ifdef DISPLAY
cout << "Deleting array of size "
<< p->arraySize << endl;
#endif
delete[] p->memPtr; // delete array
}
else {
#ifdef DISPLAY
cout << "Deleting: "
<< *(T *) p->memPtr << "\n";
#endif
delete p->memPtr; // delete single element
}
}

// Restart the search.
break;
}

} while(p != gclist.end());

#ifdef DISPLAY
cout << "After garbage collection for ";
showlist();
#endif

return memfreed;
}

template <class T, int size>
T * GCPtr<T, size>::operator=(T *t) {
list<GCInfo<T> >::iterator p;

p = findPtrInfo(addr);
p->refcount--;

p = findPtrInfo(t);
if(p != gclist.end())
p->refcount++;
else {
// Create and store this entry.
GCInfo<T> gcObj(t, size);
gclist.push_front(gcObj);
}

addr = t; // store the address.

return t;
}

template <class T, int size>
GCPtr<T, size> & GCPtr<T, size>::operator=(GCPtr &rv) {
list<GCInfo<T> >::iterator p;

p = findPtrInfo(addr);
p->refcount--;

p = findPtrInfo(rv.addr);
p->refcount++; // increment ref count

addr = rv.addr;// store the address.

return rv;
}

template <class T, int size>
void GCPtr<T, size>::showlist() {
list<GCInfo<T> >::iterator p;

cout << "gclist<" << typeid(T).name() << ", "
<< size << ">:\n";
cout << "memPtr refcount value\n";

if(gclist.begin() == gclist.end()) {
cout << " -- Empty --\n\n";
return;
}

for(p = gclist.begin(); p != gclist.end(); p++) {
cout << "[" << (void *)p->memPtr << "]"


<< " " << p->refcount << " ";
if(p->memPtr) cout << " " << *p->memPtr;
else cout << " ---";
cout << endl;
}
cout << endl;
}


template <class T, int size>
typename list<GCInfo<T> >::iterator
GCPtr<T, size>::findPtrInfo(T *ptr) {

list<GCInfo<T> >::iterator p;
// Find ptr in gclist.
for(p = gclist.begin(); p != gclist.end(); p++)
if(p->memPtr == ptr)
return p;

return p;
}

template <class T, int size>
void GCPtr<T, size>::shutdown() {

if(gclistSize() == 0) return; // list is empty

list<GCInfo<T> >::iterator p;

for(p = gclist.begin(); p != gclist.end(); p++) {
// Set all reference counts to zero
p->refcount = 0;
}

#ifdef DISPLAY
cout << "Before collecting for shutdown() for "
<< typeid(T).name() << "\n";
#endif

collect();

#ifdef DISPLAY
cout << "After collecting for shutdown() for "
<< typeid(T).name() << "\n";
#endif
}


if(gclistSize() == 0) return; // list is empty

list<GCInfo<T> >::iterator p;

for(p = gclist.begin(); p != gclist.end(); p++) {
// Set all reference counts to zero
p->refcount = 0;
}

#ifdef DISPLAY
cout << "Before collecting for shutdown() for "
<< typeid(T).name() << "\n";
#endif

collect();

#ifdef DISPLAY
cout << "After collecting for shutdown() for "
<< typeid(T).name() << "\n";
#endif
}
#endif
编译的时候提示出错: 主要是红色部分类型识别不了,不明白为什么 请大家看看 下面是编译的提示信息。
C:\Users\hxf\Desktop\myworkspace\collect\gc.h|231|error: expected ';' before 'p'|

[解决办法]
代码太长。。没看。。
只看这一句的话,你可以在前面加个typename 试试
[解决办法]
楼主,找本C++ primer,恶补C++基础吧。
明明是代码问题,缺了typename。

读书人网 >C++

热点推荐