Listing 2
#include <cassert>
#include <typeinfo>
const bool deletable = true;
// used to uniquely identify the return type of new operations
template<typename T>
class new_ptr {
public:
new_ptr(T* x) : m(x) { };
T* m;
};
// used to cast from a raw pointer (generated from a new operation) to
// a new_ptr
template<typename T>
inline new_ptr<T> new_cast(T* x) {
return new_ptr<T>(x);
};
// this pointer type does not allow deletion of the resource
template<typename T, bool deleteable_B = false>
class ptr {
public:
ptr() : m(NULL) { };
ptr(const ptr& x) : m(x.m) { };
ptr(T* x) : m(x) { };
ptr(const ptr<T, deletable>& x) : m(x.raw_pointer()) { };
T* operator->() const {
return m;
}
T& operator*() {
return m;
}
const T& operator*() const {
return m;
}
bool operator==(ptr x) const {
return m == x.m;
}
bool operator!=(ptr x) const {
return m != x.m;
}
void Release() {
m = NULL;
}
static ptr null() {
return ptr();
}
void operator=(const ptr<T, true>& x) {
m = x.raw_pointer();
}
private:
T* m;
};
// this pointer type allows manual deletion of the referenced resource but
// does not automatically destroy!
// This differs from the ptr template by introducing a Delete() function
template<typename T>
class ptr<T, true> {
public:
ptr() : m(NULL) { };
ptr(const ptr& x) : m(x.m) { };
explicit ptr(const new_ptr<T>& x) : m(x.m) { };
T& operator*() {
return m;
}
const T& operator*() const {
return m;
}
void Delete() {
assert(m != NULL);
delete m;
assert((m = NULL) == NULL);
}
void Release() {
m = NULL;
}
T* operator->() const {
return m;
}
T* raw_pointer() const {
return m;
}
static ptr null() {
return ptr();
}
operator ptr<T, false>() const {
return m;
}
void operator=(new_ptr<T> x) {
m = x.m;
}
private:
T* m;
};