I am making a little pointer class to take care of pointers... it can auto-delete stuff for you if you wish with whatever you tell it to (p.set_destroyer(&operator delete)) and keeps reference counting, etc. etc.. (Thanks to rip-off for his pointer class to stand as a "learning base".)
Now, I made some functions and the pointer is almost usable... Now the problem is, that with a little test class I got what was not expected (no deletion):
[[[test()]]][[[test()]]]
0 0[[[test()]]]
0 0x3d3d48[[[~test()]]]
Press ENTER to continue.
#include "Benefit_Pointer.h"
#include <iostream>
using namespace std;
struct test {
test() { cout << "[[[test()]]]"; }
test(const test&) { cout << "[[[test(const test&)]]]"; }
~test() { cout << "[[[~test()]]]"; }
};
int main(int argc, char **argv) {
benefit::pointer<test> p;
p.set_destroyer(&operator delete);
p = new test();
p.destroy();
p = new test();
benefit::pointer<test> pp = p;
p.destroy();
pp.destroy();
cout << "\n\n" << p.data(false) << " " << pp.data(false);
p = new test();
test *rp = p;
p.destroy();
cout << "\n\n" << p.data(false) << " " << rp;
delete rp;
}
I was expecting some more [[[~test()]]]s... So, it should have been:
con
des
con
des
con
des
Although it was:
con
con
con
des
So it seems that EVERYTHING works besides the pointer deleting the stuff...
Here is what the pointer looks like (benefit_assert.h just defines ASSERT which becomes BENEFIT_ASSERT which becomes benefit::assert(val, __FILE__, __PRETTY_FUNCTION__, __LINE__)):
#ifndef BENEFIT_POINTER_H_
#define BENEFIT_POINTER_H_
#include "Benefit_Null.h"
#include "Benefit_Assert.h"
namespace benefit {
template<class TYPE>
class pointer {
protected:
class data_wrapper {
protected:
unsigned m_refcount;
TYPE *m_data;
pointer<TYPE> *m_currpointer;
public:
TYPE *data() { return m_data; }
data_wrapper(TYPE *data): m_refcount(1), m_data(data), m_currpointer(NULL) {}
~data_wrapper() {
ASSERT(m_refcount == 0);
if (data() && m_currpointer && m_currpointer->get_destroyer())
(*(m_currpointer->get_destroyer()))(data());
}
void releaseref(pointer<TYPE> *currpointer) {
if (currpointer != m_currpointer)
m_currpointer = currpointer;
if (--m_refcount < 1)
delete this;
}
void addref() {
++m_refcount;
}
};
mutable data_wrapper *m_data;
void (*m_des)(void*);
public:
pointer(): m_data(NULL), m_des(NULL) {}
pointer(TYPE *data): m_data(new data_wrapper(data)), m_des(NULL) {}
pointer(const pointer<TYPE> &other): m_data(other.m_data), m_des(other.m_des) {
if (m_data)
m_data->addref();
}
~pointer() {
destroy();
}
pointer<TYPE> &operator =(const pointer<TYPE> &other) {
if (m_data)
m_data->releaseref(this);
m_data = other.m_data;
if (m_data)
m_data->addref();
return *this;
}
pointer<TYPE> &operator =(TYPE *other) {
if (m_data)
m_data->releaseref(this);
m_data = (other) ? new data_wrapper(other) : NULL;
return *this;
}
void set_destroyer(void (*des)(void*)) {
m_des = des;
}
typedef void (*funcptr)(void*); // :D
funcptr get_destroyer() { // :D
return m_des;
}
TYPE *data(bool addref = true) {
if (!m_data)
return NULL;
else
if (addref)
m_data->addref();
return m_data->data();
}
operator TYPE*() {
return data();
}
TYPE *operator ->() {
return data(false);
}
#if TYPE != void
struct null_deref_exception {};
TYPE &operator *() {
if (!data(false))
throw null_deref_exception;
return *m_data->data(false);
}
#endif
void destroy() {
if (m_data)
m_data->releaseref(this);
m_data = NULL;
}
void destroy(void (*des)(void*)) {
void (*old)(void*) = m_des;
set_destroyer(des);
destroy();
set_destroyer(old);
}
};
}
#endif
Sorry for the long pointer class... I just have a 0 idea of why this is happening... I mean... I DID set the deleter, right?
THANKS!