Nowhere documentated lie the smart pointers. I read quite a lot of topics about them, but I never saw a snippet of code. If I understand correctly, they should be classes defined with a template, containing a pointer to the templated type or class. I was playing with this concept and came up with this:
You're sharing ownership, so each owner will delete the same pointer, resulting in multiple deletes.
Consider the following:
1 2 3 4 5 6 7 8
{
SmPointer<int> a(newint); // allocated
{
SmPointer<int> b(a); // copied to 'b'
} // b's dtor deleted the int here
*a = 5; // EXPLODE, the int has already been deleted by b
} // EXPLODE, 'a' deletes the pointer again, after 'b' already deleted it
I'd come up with a more complete example, but I'm at work now so I can't! Maybe when I get home.
template <typename T>
class SmPointer
{
private:
T* ptr; // the actual data we're pointing to
unsigned* ref; // reference count keeping track of all SmPointer's accessing this data
// a function to decrement the reference count
void DecRef()
{
if(ref)
{
--(*ref); // dec the ref
if(!*ref) // if it's zero
{
// no more Smart Pointers using this data, so clean up
delete ptr;
delete ref;
}
}
}
public:
SmPointer() : ptr(0), ref(0) { } // default ctor
SmPointer(const SmPointer<T>& r) // copy ctor
: ptr(r.ptr), ref(r.ref)
{
// increment the ref count
if(ref)
++(*ref);
}
explicit SmPointer(T* p) // ctor from a pointer
: ptr(p), ref( newunsigned(1) ) // start the ref count at 1
{ }
SmPointer<T>& operator = (const SmPointer<T>& r) // assignment operator
{
// abandon the previous pointer by decreasing the ref
DecRef();
// then adapt this new pointer
ptr = r.ptr;
ref = r.ref;
if(ref)
++(*ref);
return *this;
}
~SmPointer() // dtor
{
// abandon by decreasing the ref
DecRef();
}
};
Thanks for the replies Disch, your codes always impress me. I just have a few questions, what is the explicit keyword, is unsigned by it's self a type and what are it's limits?
explicit is mainly to prevent you from accidentally reassigning a pointer to a smart pointer that you didn't mean to. Typically via a function call:
1 2 3 4 5 6 7 8 9 10 11 12 13
void AFunction(SmPointer<int> p)
{
// ...
}
int main()
{
int myint = 5;
AFunction( &myint ); // compiler errors with explicit keyword
// compiles just fine without it, but the program will explode because the smart
// pointer will try to delete myint
}