首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

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

2012-09-24 
泛型编程上的一个问题#ifndef _GC_H_#define _GC_H_#include iostream#include list#include typeinf

泛型编程上的一个问题
#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。

热点排行