Re: Smart Pointer help
Protoman wrote:
Here's a non intrusive reference counting smart pointer class I'm
working on; I keep getting a "22 C:\Dev-Cpp\SmrtPtr.hpp ISO C++ forbids
declaration of `SmrtPtrDB' with no type" error.
Code:
SmrtPtr.hpp
#pragma once
non-standard pragma.
template<class T>
class SmrtPtr
{
public:
explicit SmrtPtr(T* obj):ptr(obj)
reasonable so far although most smart-pointers have an implicit
constructor from the pointer type. Allows you to do this:
SmrtPtr< T > getT()
{
return new T( params );
}
{
DataBase.add();
for(;;) // never ending loop, there is no "break"
{
if(isInvalid())
delete this;
}
delete this can be used only on classes created on the heap (i.e. with
new). Most smart pointers are created on the stack. Self-deletion would
be undefined. Note that this line will not cause loop termination.
}
SmrtPtr(const SmrtPtr<T>& rhs):ptr(rhs.obj){DataBase.add()}
~SmrtPtr(){delete ptr; DataBase.sub()}
T& operator*(){return *ptr;}
T* operator->(){return ptr;}
These two should possibly be const functions. Not that they will return
pointers to const. (If you want that you use SmrtPtr< const T >) but
because it allows you to use these on temporaries.
T** operator&(){return &ptr;}
very unusual to overload this.
private:
static SmrtPtrDB<T> DataBase;
There will be a DataBase for each type T, not for each object being
pointed to.
bool isInvalid()
another non-const function that probably should be const.
{
for(;;)
this loop at least will end beacuse you return in the middle.
if(!DataBase.status())
return true;
else return false;
}
If you are going to test a boolean condition then return the result
directly, thus:
return !Database.status();
T* ptr;
};
SmrtPtrDB.hpp
#pragma once
#include "SmrtPtr.hpp"
template<class T>
class SmrtPtrDB
{
public:
SmrtPtrDB():num(0){}
~SmrtPtrDB(){}
void add(){num++;}
void sub(){num--);
int status(){return num;}
private:
int num;
};
Could you help me out on this? I'm not even sure if I'm coding the
non-intrusive reference counting correctly. Thanks!!!!!
But you're reference counting the wrong thing. If you're not actually
going to use tr1::shared_ptr / boost::shared_ptr or Loki then at least
look up the source for boost or Loki to see how it's done. If their
code in places looks rather complex, that is because writing a good
non-intrusive smart-pointer is not as trivial as it first seems.
(Actually some of the complexity in boost comes from sharing code with
other types of smart-pointer. Much of the complexity also comes from
custom-deleters, automatic type-conversion and portability across
libraries).