Any help or ideas about linking this into my main would be greatly appreciated.
Thanks John.
Compiling using g++ -W -Wall -ansi -pedantic -g SMARTPTRMAIN.cpp smart_pointer.h smart_pointer.cpp LinkedList.h LinkedList.cpp -o sp
This is the main, if the linked list section in the main is commented out it compiles.
/*
SMARTPTRMAIN.C
--------------
*/
#include "smart_pointer.h"
using namespace smart_pointers;
/*
class LINK
----------
an extremely simple linked list class
*/
class link
{
public:
smart_pointer<link> next;
int data;
};
/*
class BIG
---------
a class that takes up a lot of memory
*/
class big
{
public:
int big_array[1000000];
};
/*
TEST_SCOPE()
------------
function to test whether scope is handled properly
*/
void test_scope(void)
{
smart_pointer<big> b = new big();
smart_pointer<big> b2 = b;
//print_all_counts("test scope");
}
/*
MAIN()
------
Test the smart_pointer code
*/
int main()//int argc, char *argv[]) compiles nice
{
/*
Simple Tests
*/
smart_pointer<int> p = new int();
*p = 5;
print_all_counts("first");
smart_pointer<int> q = p;
cout << "p.getCount = " << p.getCount()<< endl;
cout << "p = " << *p << " q = " << *q << endl;
//print_all_counts("second");
smart_pointer<int> r = new int();
*r = 2;
//print_all_counts("third");
p = r;
cout << "p = " << *p << " q = " << *q << " r = " << *r << endl;
//print_all_counts("fourth");
q = p;
cout << "p = " << *p << " q = " << *q << " r = " << *r << endl;
q = p = r = 0;
//print_all_counts("fifth");
/*
test a circular linked list, there should be no way of deleting
this list - in other words, garbage is created
*/
/* This is the part that is commented out. So that we can compile the code
smart_pointer<link> l = new link();
l->data = 1;
assert(l->data == (*l).data);
l->next = new link();
l->next->next = new link();
l->next->next->next = l;
l = 0;
print_all_counts("after linked list");
*/
/*
test the allocation/deletion of big objects
Warning: make sure that your code deallocates properly before
trying to do this. If it doesn't deallocate, then you will be
trying to allocate 1G of memory which will usually mean bad
things. If it does deallocate, you'll only use 1M of memory for
this part.
*/
smart_pointer<big> b = new big();
for (int i=0; i < 1000; i++)
b = new big();
//print_all_counts("after big");
/*
test that scoping doesn't cause any problem
*/
test_scope();
//print_all_counts("last");
return 0;
}
/*
Filename: LinkedList.cpp
Author:
Description: Implements methods defined in LinkedList.h
*/
#include "LinkedList.h"
#include <iostream>
#include <iterator>
using namespace std;
#ifdef __LINKEDLIST_H_
#ifndef __LINKEDLIST_CPP_
#define __LINKEDLIST_CPP_
template <class T> LinkedList<T>::LinkedList(){
first = NULL;
_size = 0;
}
template <class T> void LinkedList<T>::insert(T *s){
Node *n = new Node(s, NULL, NULL);
if(first == NULL){
first = n;
last = n;
}
else{
last->setNext(n);
n->setPrev(last);
last = n;
}
_size++;
}
template <class T> void LinkedList<T>::remove(T *s){
Node *n = first;
while(n != NULL){
if(n->getItem() == s){
if(n == first)
first = n->getNext();
if(n == last)
last = n->getPrev();
if(n->getNext() != NULL)
n->getNext()->setPrev(n->getPrev());
if(n->getPrev() != NULL)
n->getPrev()->setNext(n->getNext());
return;
}
n = n->getNext();
}
}
template <class T> LinkedList<T>::~LinkedList(){
}
template <class T> void LinkedList<T>::insert(iterator pos, T item){
Node *n = new Node(&item, pos.getNode(), pos.getNode()->getPrev());
if(first == NULL){
first = n;
last = n;
}
else{
pos.getNode()->setPrev(n);
}
_size++;
}
template <class T> void LinkedList<T>::remove(iterator pos){
Node *n = pos.getNode();
if(n == first)
first = n->getNext();
if(n == last)
last = n->getPrev();
if(n->getNext() != NULL)
n->getNext()->setPrev(n->getPrev());
if(n->getPrev() != NULL)
n->getPrev()->setNext(n->getNext());
}
#endif
#endif
/*
Filename: LinkedList.h
Author:
Description:
*/
#include <iterator>
#include <iostream>
#include <cassert>
#ifndef __LINKEDLIST_H_
#define __LINKEDLIST_H_
using namespace std;
template <class T> class LinkedList{
public:
LinkedList();
virtual void insert(T *s);
virtual void remove(T *s);
virtual ~LinkedList();
class Node{
public:
Node(T *a, Node *n, Node *p){
i = a;
next = n;
prev = p;
};
Node(const Node &other){
i = other.i;
next = other.next;
prev = other.prev;
};
virtual ~Node(){};
T *getItem(){ return i; };
Node *getNext(){ return next; };
Node *getPrev(){ return prev; };
void setNext(Node *n){ next = n; };
void setPrev(Node *p){ prev = p; };
bool operator<(Node &other){ return ((*i)<(*(other.i))); };
T &operator*(){
return *i;
};
T *operator->(){
return i;
};
private:
T *i;
Node *next;
Node *prev;
};
class iterator{
public:
// canonical class stuff
iterator(const iterator &other):
_index(other._index), _array(other._array) {
_currpos = other._currpos;
};
iterator(LinkedList *arr, int where=0):_array(arr),
_index(where){
if(_index >= arr->_size)
_currpos = NULL;
else{
_currpos = _array->first;
for(int i = 0; i < _index; i++){
_currpos = _currpos->getNext();
if(_currpos == NULL)
break;
}
}
};
iterator(){
_array=0;
_index=0;
_currpos = 0;
};
virtual ~iterator(){};
iterator &operator=(const iterator &other){
_array = other._array;
_currpos = other._currpos;
_index = other._index;
return *this;
};
// increment/decrement operators
iterator &operator++(){
_currpos = _currpos->getNext();
_index++;
return *this;
};
iterator &operator--(){
if(_index == _array->_size)
_currpos = _array->last;
else _currpos = _currpos->getPrev();
_index--;
return *this;
};
// note that the dummy parameter simply forces these operators
// to be postfix operators. This is one of the many places
// where C++ is a bit ugly.
iterator operator++(int){
_currpos = _currpos->getNext();
_index++;
return *this;
};
iterator operator--(int){
if(_index == _array->_size)
_currpos = _array->last;
else _currpos = _currpos->getPrev();
_index--;
return *this;
};
// checking for inequality
bool operator!=(const iterator &other){
return !((*this)==other);
};
// equality checking
bool operator==(const iterator &other){
return (_index==other._index&&_array==other._array);
};
// dereference operators
T &operator*(){
return *(_currpos->getItem());
};
T *operator->(){
return &(*this);
};
// basic iterator arithmetic
// these methods are needed for random access iterators
iterator operator-(int diff){
iterator iter = *this;
for(int i = 0; i < diff; i++)
iter--;
return iter;
};
ptrdiff_t operator-(const iterator &other){
return _index-other._index;
};
iterator operator+(int diff){
iterator iter = *this;
for(int i = 0; i < diff; i++){
iter++;
//iter._currpos = iter._currpos->getNext();
//iter._index++;
}
return iter;
};
bool operator<(const iterator &other){
return _index<other._index;
};
Node *getNode(){
return _currpos;
};
// for the stl algorithms to work on these iterators, we must
// define the following types
typedef random_access_iterator_tag iterator_category;
typedef int value_type;
typedef ptrdiff_t difference_type;
typedef int * pointer;
typedef int reference;
private:
int _index;
LinkedList *_array;
Node *_currpos;
};
virtual iterator begin(){
return iterator(this, 0);
};
virtual iterator end(){
return iterator(this, _size);
};
virtual void insert(iterator pos, T item);
virtual void remove(iterator pos);
protected:
int _size;
Node *first;
Node *last;
};
#include "LinkedList.cpp"
#endif
/*
Filename: smart_pointer.cpp
Author:
Description:
*/
#include <cstdio>
void print_all_counts(const char* s){
printf("%s begin\n", s);
printf("%s end\n", s);
}
/*
Filename: smart_pointer.h
Author:
Description:
*/
#ifndef MY_CLASS_H
#define MY_CLASS_H
#include <iostream>
#include <cassert>
#include "LinkedList.h"
void print_all_counts(const char* s);
namespace smart_pointers{
using namespace std;
template < typename T > class smart_pointer{
class RC{
public:
int count; // Reference count
void IncreaseReferenceCount(){ // Increment the reference count
count++;
}
int DecrementReferenceCount(){ // Decrement the reference count and return the reference count.
return --count;
}
int getCount(){ // returns the reference count
return count;
}
};
public:
T* pData; // pointer
RC* reference; // Reference count
smart_pointer() : pData(0), reference(0){
reference = new RC(); // Create a new reference
reference->AddRef(); // Increment the reference count
}
smart_pointer(T* pValue) : pData(pValue), reference(0){
reference = new RC(); // Create a new reference
reference->IncreaseReferenceCount(); // Increment the reference count
}
smart_pointer(const smart_pointer<T>& smart) : pData(smart.pData), reference(smart.reference){
// Copy constructor
// Copy the data and reference pointer
// and increment the reference coun
reference->IncreaseReferenceCount();
}
~smart_pointer(){ // Destructor
if(reference->DecrementReferenceCount() == 0){ // if reference become zero delete the data
delete pData;
delete reference;
}
}
int getCount(){
return reference->getCount();
}
T& operator* (){
return *pData;
}
T* operator-> (){
return pData;
}
smart_pointer<T>& operator = (const smart_pointer<T>& smart){
// Assignment operator
if (this != &smart){ // Avoid self assignment
// Decrement the old reference count
// if reference become zero delete the old data
if(reference->DecrementReferenceCount() == 0){
delete pData;
delete reference;
}
// Copy the data and reference pointer
// and increment the reference count
pData = smart.pData;
reference = smart.reference;
reference->IncreaseReferenceCount();
}
return *this;
}
};
}
#endif

New Topic/Question
Reply




MultiQuote



|