473,406 Members | 2,867 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Two smartpointer designs

I've made two smartpointers that I'd like to share. Improvements and
comments are welcome.

The key to both is that there should be no access to the managed
object, and all operations should be done on the smartpointers. Both
are designed in a similar way, where a userclass inherits from a
template and the smartpointer is defined as an internal class of the
template;

The first one is an automatic refcount smartpointer where the object
pointed to keeps track of the current refcount, and the object gets
destroyed if the refcount goes to 0. All refcount management is
automatic.

The second is called a safepointer, and the managed object will
automatically clear all safepointers which references it when
destroyed. Destruction is done through a smartpointer's destroy
function.

I'm including a testfile which shows how they are used, followed by
the 2 template files:
// ConsoleTests.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"
#include "../../common/autorefcount.h"
#include "../../common/safepointer.h"

class A;
class A : public TAutoRefable<A*>
{
public:
static ARPtr Create(int x){return ARPtr(new A(x));} // create an
instance of A

int GetX(){return mX;}
private:
A(int x) : mX(x){} // keep constructors private in inherited classes,
and use Create to instanciate

int mX;
};

void TestAutoRefPointer(){
A::ARPtr c;
bool valid = c.IsValid(); // false

c = A::Create(1);
if (c.IsValid()) { // true
int x = c->GetX();
}

DWORD refcount = c.GetRefCount();// refcount = 1

{
A::ARPtr d(c);
refcount = c.GetRefCount();// refcount = 2
{
A::ARPtr e;
e = c;
refcount = c.GetRefCount();// refcount = 3
}
refcount = c.GetRefCount();// refcount = 2
}
refcount = c.GetRefCount();// refcount = 1

valid = c.IsValid(); // true
c.Clear(); // refcount = 0, object gets destroyed
refcount = c.GetRefCount();// refcount = 0
valid = c.IsValid(); // false

}
class S;
class S : public TSafeObj<S*>
{
public:
static SPtr Create(int x){return SPtr(new S(x));} // create an
instance of S
int GetX(){return mX;}

private:
S(int x) : TSafeObj<S*>(5), mX(x){}// keep constructors private in
inherited classes, and use Create to instanciate
int mX;
};
void TestSafePointer(){
S::SPtr c;

bool valid = c.IsValid(); // false

c = S::Create(1);
if (c.IsValid()){ // true
int x = c->GetX();
}

S::SPtr d(c);
S::SPtr e;
e = c;

d.Destroy(); // destroys object, and clears all SafePointers to it
if (c.IsValid() || d.IsValid() || e.IsValid()) {// false
int x = c->GetX();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
TestAutoRefPointer();
TestSafePointer();
return 0;
}
// autorefcount - ptr with auto refcount

#pragma once
#include "comdef.h"
template <class Tclass TAutoRefable
{
public:
class ARPtr
{
public:
ARPtr() : mPtr(NULL){}
ARPtr(T p) : mPtr(p) {
if (p) {
p->AddRef();
}
}
ARPtr(const ARPtr& s) : mPtr(s.mPtr){
if (mPtr) {
mPtr->AddRef();
}
}
~ARPtr()
{
if (mPtr){
mPtr->SubRef();
}
}
DWORD GetRefCount(){return (mPtr) ? mPtr->mRefCount : 0;}

T operator -(){return mPtr;}
ARPtr& operator =(const ARPtr& that){
if (this != &that) {
if (mPtr){
mPtr->SubRef(); // deletes object if refcount goes to 0, so mPtr
can point to freed mem after this.
}
if (that.mPtr) {
that.mPtr->AddRef();
}
mPtr = that.mPtr;
}
return *this;
}

void Clear(){
if (mPtr){
mPtr->SubRef();
}
mPtr = NULL;
}

bool IsValid(){return mPtr != NULL;}

private:
T mPtr;
};

// initial values for event and subsciber dynamic arrays
static ARPtr Create(){return ARPtr(NULL);} // override this with more
interesting actions
protected: // keep constructors and destructors protected/private in
inherited classes
TAutoRefable() : mRefCount(0){}
virtual ~TAutoRefable(){}

private:
friend ARPtr;
void AddRef(){mRefCount++;}
void SubRef(){--mRefCount; if (mRefCount == 0) delete this;}

DWORD mRefCount;
};
// SafePtr - clears all safeptrs when object is destroyed

#pragma once
#include "comdef.h"
#include "objectarray.h"

template <class Tclass TSafeObj
{
public:
class SPtr
{
public:

SPtr() : mPtr(NULL){}
SPtr(T p) : mPtr(p) {if (mPtr) mPtr->AddSPtr(this);}
SPtr(const SPtr& s) : mPtr(s.mPtr){
if (mPtr) mPtr->AddSPtr(this);
}
~SPtr(){if (mPtr) mPtr->RemoveSPtr(this);}

void Destroy(){
if (mPtr){
mPtr->RemoveSPtr(this);
delete mPtr; // mPtr clears out other sptrs
mPtr = NULL;
}
}
T operator -(){return mPtr;}
SPtr& operator =(const SPtr& that){
if (this != &that) {
if (mPtr) mPtr->RemoveSPtr(this);
if (that.mPtr) that.mPtr->AddSPtr(this);
mPtr = that.mPtr;
}
return *this;
}

void Clear(){
if (mPtr) mPtr->RemoveSPtr(this);
mPtr = NULL;
}

bool IsValid(){return mPtr != NULL;}

private:
friend TSafeObj;
T mPtr;

};

static SPtr Create(){return SPtr(NULL);} // override with more useful
actions

protected: // keep destructor and constructor protected/private in
inherited classes
friend SPtr;

TSafeObj(DWORD ptrCount) : mSafePtrs(ptrCount){} // set up initial
pointercount

virtual ~TSafeObj(){
for (DWORD i = 0; i < mSafePtrs.Size(); ++i) mSafePtrs[i]->mPtr =
NULL;
}
private:
typedef TObjectArray<SPtr*SafePtrArray;

void AddSPtr(SPtr* sptr){mSafePtrs.Add(sptr);}
void RemoveSPtr(SPtr* sptr){mSafePtrs.RemoveObj(sptr);}

SafePtrArray mSafePtrs; // Sptrs to this object
};

Dec 1 '07 #1
0 1155

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

39
by: Scotter | last post by:
Okay I think my title line was worded misleadingly. So here goes again. I've got quite 20 identical MDB files running on an IIS5 server. From time to time I need to go into various tables and add...
145
by: Mark Johnson | last post by:
Oddly enough, I found it difficult, using Google, to find a list of best-of sites based on the quality of their css packages. So I'd ask. Does anyone know of particularly good sites which are in...
2
by: Tobias Kilian | last post by:
Hi Ng ! I wrote a SmartPointer class which holds a doubled linked list to all its copies to ensure that all copies are holding the same pointer, even if one copy changes later. If the last...
15
by: mathieu | last post by:
Hi, I have implemented a SmartPointer class following the implementation proposed by Bill Hubauer(*). But I also override the operator * () template<class ObjectType> class SmartPointer {...
2
by: coder_lol | last post by:
MS VS 7.0 happily resolves by SmartPointer and Inheritance, but I got to use another target compiler and it does not accept user conversion for templates. Can I forced a recast somehow? I have...
0
by: service0073 | last post by:
Designs For Fine Jewelry Pieces Fine jewelry is created from the finest precious metals and the gems that are set in these metals could be what makes the jewelry so fine. Jewelry lovers can wear...
8
by: Prisoner at War | last post by:
As 16:9 widescreens become more common, are there any designs which are specifically created to somehow exploit any advantages offered by letterbox dimensions? How to remain backwards-compatible...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.